Graph Valid Tree

题目:

Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.

Example

Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return true.

Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], return false.

分析:

如果一个graph是valid tree,需要check如下两个方面:

1. 是否存在cycle
2. connected component是否为1

这题目解法的关键所在是把现有的vector-edge换成vector-neighbor,在这个基础上,dfs和bfs都变得容易了很多。因为在建立vector-neighbor的时候是双向添加的,所以无论dfs还是bfs,都需要一个去除冗余的过程。例如:

0<1, 2, 3>
1<0, 4>
2<0>
3<0>
4<1>

这种情况下,在访问1的时候,不需要check 0的问题。

如果是dfs的话,可以直接用一个variable parent来by-pass一次循环。

如果是bfs的话,需要用一个hash table来储存check过的元素。

解法dfs:

class Solution {
public:
    /**
     * @param n an integer
     * @param edges a list of undirected edges
     * @return true if it's a valid tree, or false
     */
    bool dfsHasCycle(vector<vector<int> > &neighbors, int child, int parent, vector<bool> &visited) {
        if (visited[child] == true) {
            return true;
        }
        visited[child] = true;
        for (int i = 0; i < neighbors[child].size(); i++) {
            if (neighbors[child][i] == parent) {
                continue;
            }
            if (dfsHasCycle(neighbors, neighbors[child][i], child, visited) == true) {
                return true;
            }
        }
        return false;
    } 

    bool validTree(int n, vector<vector<int>>& edges) {
        // Write your code here
        vector<vector<int> > neighbors(n);
        for (int i = 0; i < edges.size(); i++) {
            int first = edges[i][0];
            int second = edges[i][1];
            neighbors[first].push_back(second);
            neighbors[second].push_back(first);
        }
        vector<bool> visited(n, false);
        if (dfsHasCycle(neighbors, 0, -1, visited) == true) {
            return false;
        }
        for (int i = 0; i < n; i++) {
            if (visited[i] == false) {
                return false;
            }
        }
        return true;
    }
};

解法bfs:

class Solution {
public:
    /**
     * @param n an integer
     * @param edges a list of undirected edges
     * @return true if it's a valid tree, or false
     */
    bool validTree(int n, vector<vector<int>>& edges) {
        // Write your code here
        vector<vector<int> > neighbors(n);
        for (int i = 0; i < edges.size(); i++) {
            int first = edges[i][0];
            int second = edges[i][1];
            neighbors[first].push_back(second);
            neighbors[second].push_back(first);
        }
        vector<bool> visited(n, false);
        queue<int> Q;
        Q.push(0);
        visited[0] = true;
        unordered_set<int> checked;
        while (!Q.empty() ) {
            int curr = Q.front();
            checked.insert(curr);
            Q.pop();
            for (int i = 0; i < neighbors[curr].size(); i++) {
                if (checked.find(neighbors[curr][i]) != checked.end() ) {
                    continue;
                }
                if (visited[neighbors[curr][i] ] == true) {
                    return false;
                } else {
                    Q.push(neighbors[curr][i]);
                    visited[neighbors[curr][i]] = true;
                }
            }
        }
        for (int i = 0; i < n; i++) {
            if (visited[i] == false) {
                return false;
            }
        }
        return true;
    }
};

results matching ""

    No results matching ""