Union-Find (Connected Components)
The data structure behind Kruskal’s MST, network connectivity and image-region labeling: a disjoint-set (union-find) that answers "are these two connected?" in near-constant time. Implement it with union by rank and path compression, then count the connected components. Solve it in Python or TypeScript, with hidden tests.
The problem
You are given n nodes labelled 0…n-1 and a list of undirected edges. Two nodes are in the same component if there is a path of edges between them. Return the number of connected components after applying every edge. Implement it with a disjoint-set (union-find) — do not just BFS the graph.
n = 5, edges = [[0,1],[1,2],[3,4]]2n = 4, edges = []4n = 3, edges = [[0,1],[1,2],[0,2]]1- 1 ≤ n ≤ 10⁵, 0 ≤ edges.length ≤ 10⁵
- Use path compression in find and union by rank/size — together they give near-O(1) amortized (inverse-Ackermann) operations.
- A redundant edge (both endpoints already in the same set) must not change the count.
Your turn — write it
Edit the stub, hit Run (or ⌘/Ctrl + Enter), and watch the hidden tests. Stuck? the hints are right above and Reveal solution is one click away.
Implement count_components(n, edges): build a disjoint-set over n nodes, union the endpoints of every edge, then return how many distinct roots remain. Use path compression + union by rank so it scales.
- Keep a
parentarray where each node points at another node in its set; a root points at itself. find(x)walks parents to the root. Compress the path as you go (point nodes straight at the root or their grandparent) so future finds are fast.union(a, b)finds both roots; if different, attach the smaller-rank tree under the larger to keep trees shallow.- The answer is the number of nodes that are their own root — equivalently,
len({find(i) for i in range(n)}).
Explore the topic
See this challenge alongside everything else on the same subject — handbooks, system designs, algorithms and tools, in one place.