LeetCode 261. Graph Valid Tree
Given
For example:
Given
Given
Hint:
Given
Note: you can assume that no duplicate edges will appear in
Method 1: Union-Find Algorithm
If could't think up Union-Find method, it is also Ok to to use DFS to detect cycle. If cycle found, that is not a valid graph tree.
Step:
1: first build up hashmap hashmap[first].push_back(second), hashmap[second].push_back(first)
2: Make all the node unvisited.
3: Loop all the node, if found an unvisited node, using dfs to detect cycle. Note: here we need to pass the parent node in to dfs function
bool dfs(nodesMap, currNode, parentNode, visited) {
visited[curreNode] = true;
for(v : edges) {
if(unvisited) {if(dfs(nodesMap, v, currentNode, visited)) return true;}
else if( *v != parentNode) return ture//cycle detected
}
return false//there is no cycle.
}
if(dfs) return false//cycle in the undirected graph, that is not a valid tree.
Beside checking whether there is a cycle, we also need to check whether the given nodes forms a forest.
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. For 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
. Hint:
Given
n = 5
and edges = [[0, 1], [1, 2], [3, 4]]
, what should your return? Is this case a valid tree? Show More Hint Note: you can assume that no duplicate edges will appear in
edges
. Since all edges are undirected, [0, 1]
is the same as [1, 0]
and thus will not appear together in edges
. Method 1: Union-Find Algorithm
#include
#include
using namespace std;
// this is actually to use union-find.
bool find(vector& id, int p, int q) {
return id[p] == id[q];
}
int root(vector& id, int p) {
while(p != id[p]) {
p = id[p];
}
return p;
}
void unite(vector& id, int p, int q) {
int root_p = root(id, p);
int root_q = root(id, q);
id[root_p] = root_q;
}
bool isValidTree(int n, vector< vector >& edges) {
if(n < 0 || (n - 1) != edges.size()) return false;
vector id(n);
for(int i = 0; i < n; ++i) {
id[i] = i;
}
for(int i = 0; i < edges.size(); ++i) {
if(find(id, edges[i][0], edges[i][1])) {
return false;
} else {
unite(id, edges[i][0], edges[i][1]);
}
}
return true;
}
int main(void) {
vector< vector > edges{{0, 1}, {0, 2}, {0, 3}, {1, 4}};
vector< vector > edges_1{{0, 1}, {1, 2}, {2, 3}, {1, 3}, {1, 4}};
cout << isValidTree(5, edges) << endl;
cout << isValidTree(5, edges_1) << endl;
}
If could't think up Union-Find method, it is also Ok to to use DFS to detect cycle. If cycle found, that is not a valid graph tree.
Step:
1: first build up hashmap hashmap[first].push_back(second), hashmap[second].push_back(first)
2: Make all the node unvisited.
3: Loop all the node, if found an unvisited node, using dfs to detect cycle. Note: here we need to pass the parent node in to dfs function
bool dfs(nodesMap, currNode, parentNode, visited) {
visited[curreNode] = true;
for(v : edges) {
if(unvisited) {if(dfs(nodesMap, v, currentNode, visited)) return true;}
else if( *v != parentNode) return ture//cycle detected
}
return false//there is no cycle.
}
if(dfs) return false//cycle in the undirected graph, that is not a valid tree.
Beside checking whether there is a cycle, we also need to check whether the given nodes forms a forest.