Graph Valid Tree
You have a graph of `n` nodes labeled from `0` to `n - 1`. You are given an integer `n` and a list of `edges` where `edges[i] = [ai, bi]` indicates that there is an undirected edge between nodes `ai` and `bi` in the graph. Return `true` if the edges of the given graph make up a valid tree, and `false` otherwise.
Examples
Constraints
1 <= n <= 20000 <= edges.length <= 5000edges[i].length == 20 <= ai, bi < nai != biThere are no self-loops or repeated edges.
Union Find
Approach
1. Intuition: For a graph to be a valid tree, it must satisfy two conditions: it must have exactly `n - 1` edges, and it must have no cycles. 2. We can first check if `edges.length == n - 1`. If not, we can immediately return `false` because the graph is either disconnected (fewer edges) or contains a cycle (more edges). 3. If it has exactly `n - 1` edges, we just need to verify that it is fully connected (or equivalently, has no cycles). We can use Union-Find for this. 4. We iterate through the edges. For each edge `(u, v)`, we try to union `u` and `v`. 5. If they are already in the same set (i.e., they have the same root), adding this edge would create a cycle. So we return `false`. 6. If we process all edges without finding any cycles, and we started with `n - 1` edges, then the graph is a valid tree. We return `true`.
Complexity Analysis
Time complexity is nearly O(V + E) as the union find operations take almost constant time. Since E = V - 1, it is essentially O(V). Space complexity is O(V) for the parent and rank arrays.