DSA Graphs

Graph Valid Tree

A tree on n nodes has exactly n-1 edges and is connected; union-find or BFS verifies both.

Medium
Time O(V + E) Space O(V)
LeetCode
4 min read
graph union-find dfs

Problem#

Given n nodes labeled 0..n-1 and a list of undirected edges, decide whether the graph forms a valid tree.

Examples#

  • n = 5, edges = [[0,1],[0,2],[0,3],[1,4]]true
  • n = 5, edges = [[0,1],[1,2],[2,3],[1,3],[1,4]]false (cycle)

Constraints#

  • 1 <= n <= 2000, 0 <= edges.length <= 5000, no self-loops or duplicate edges.

Approach#

A tree has exactly n - 1 edges and is connected (and equivalently, has no cycle). Union-find each edge; if any edge connects already-unioned vertices, there’s a cycle. At the end, the number of edges must be n - 1 (equivalently, all nodes share one root).

Solution#

Graph Valid Tree
class Solution {
public:
bool validTree(int n, vector<vector<int>>& edges) {
if ((int)edges.size() != n - 1) return false;
vector<int> parent(n);
iota(parent.begin(), parent.end(), 0);
function<int(int)> find = [&](int x) {
while (parent[x] != x) { parent[x] = parent[parent[x]]; x = parent[x]; }
return x;
};
for (auto& e : edges) {
int a = find(e[0]), b = find(e[1]);
if (a == b) return false;
parent[a] = b;
}
return true;
}
};

Editorial#

The edges.size() == n - 1 short-circuit rules out both too-few-edges (disconnected) and too-many-edges (must contain a cycle). Union-find then verifies that each edge connects two previously separate components — equivalently, no cycle.

Complexity#

  • Time: O((V + E) * α(V)).
  • Space: O(V).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.