Skip to content
Jarviix
Pattern7 min read

Union-Find (Disjoint Set Union)

A near-O(1) data structure for connectivity questions — used in Kruskal, percolation, and dynamic graph problems.

graphunion-finddsu

Intro

Union-Find groups elements into disjoint sets and supports two operations: find(x) returns the representative of x's set, and union(x, y) merges the two sets. With path compression + union by rank, both run in essentially O(α(n)) — practically constant.

Key insight

If the question is 'are two things connected?' and the graph is built incrementally or reasoning by edges (not paths), reach for DSU before BFS/DFS.

Approach

  1. 1Initialise parent[i] = i and rank[i] = 0.
  2. 2find(x): walk parent pointers up; assign each node directly to the root on the way back (path compression).
  3. 3union(a, b): find roots; attach the lighter tree under the heavier one (union by rank).

Complexity

Time

O(α(n)) per op — effectively O(1)

Space

O(n)

Code

Snippetjava
class DSU {
    int[] parent, rank;
    DSU(int n) {
        parent = new int[n]; rank = new int[n];
        for (int i = 0; i < n; i++) parent[i] = i;
    }
    int find(int x) {
        if (parent[x] != x) parent[x] = find(parent[x]);
        return parent[x];
    }
    boolean union(int a, int b) {
        int ra = find(a), rb = find(b);
        if (ra == rb) return false;
        if (rank[ra] < rank[rb]) { parent[ra] = rb; }
        else if (rank[ra] > rank[rb]) { parent[rb] = ra; }
        else { parent[rb] = ra; rank[ra]++; }
        return true;
    }
}

Pitfalls

  • Forgetting path compression — find degrades to O(n).
  • Comparing `parent[x] == x` only at the top level — must follow until you find the root.
  • Counting unions but not components — usually you want components = initial - successful unions.

Variants & follow-ups

  • Number of Connected Components (LC 323)
  • Accounts Merge (LC 721)
  • Redundant Connection (LC 684)

Related reads