43 - 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.
Examples¶
Example 1
Input: n = 5, edges = [[0, 1], [0, 2], [0, 3], [1, 4]]
Output: true
Example 2
Input: n = 5, edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]
Output: false
Solution¶
Java Code¶
class Solution {
public boolean validTree(int n, int[][] edges) {
// A tree must have exactly n - 1 edges
if (edges.length != n - 1) {
return false;
}
// Union-Find to detect cycles and check connectivity
int[] parent = new int[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
}
for (int[] edge : edges) {
int rootX = find(parent, edge[0]);
int rootY = find(parent, edge[1]);
// If they share the same root, we found a cycle
if (rootX == rootY) {
return false;
}
// Union
parent[rootX] = rootY;
}
return true;
}
private int find(int[] parent, int i) {
if (parent[i] == i) {
return i;
}
return parent[i] = find(parent, parent[i]); // Path compression
}
}
Intuition¶
A graph is a valid tree if and only if: 1. It is fully connected (no isolated components). 2. It contains no cycles.
For an undirected graph with n nodes, these properties imply that the graph must have exactly n - 1 edges.
The Union-Find Approach¶
Since we already know a tree must have n - 1 edges, we can use Union-Find to check for cycles as we process the edges.
- Initial Check: If
edges.length != n - 1, returnfalseimmediately. - Cycle Detection: For each edge, use
findto check if both nodes already belong to the same component.- If they do, adding this edge would create a cycle.
- If they don't,
unionthem into the same component.
- Result: If we process all
n - 1edges without finding a cycle, the graph is guaranteed to be connected and acyclic (a valid tree).
Complexity Analysis¶
Time Complexity¶
\(O(E \cdot \alpha(V))\)
- \(E\) is the number of edges, \(V\) is the number of vertices.
- \(\alpha\) is the Inverse Ackermann function (effectively constant \(O(1)\)).
- Since \(E = V - 1\), this is practically \(O(V)\).
Space Complexity¶
\(O(V)\)
- To store the
parentarray for Union-Find.
Key Takeaways¶
- In an undirected graph, Tree \(\iff\) \(n-1\) edges + Connected \(\iff\) \(n-1\) edges + Acyclic.
- Union-Find is the go-to data structure for connectivity and cycle detection in undirected graphs.
- Path compression in Union-Find makes the operations nearly \(O(1)\).