Skip to content

Union-Find — Number of Islands II ​

↗ LeetCode: Number of Islands II · Hard · pattern chapter →

Asked atGoogleAmazonMeta

You have an m × n grid of water. Given positions where each (r, c) becomes land, return count of islands after each addition.

Example 1 — m=3, n=3, positions=[[0,0],[0,1],[1,2],[2,1]] → [1,1,2,3]Example 2 — m=1, n=1, positions=[[0,0]] → [1]Example 3 — m=3, n=3, positions=[[0,0],[0,0]] → [1,1] (duplicate placement is a no-op)

Constraints — 1 ≤ m·n ≤ 10⁴. Naive re-scan after every insert is O(k · mn) — k inserts × mn cells = 10⁸ ops = TLE. Union-Find is O(k · α(mn)) = 10⁴ · 4 = 4·10⁴.

Progressive Hints
Try to solve it yourself first. Reveal hints only when stuck — each hint is progressively more specific.
---
⏱️Interview timer00:00
Practice under interview pressure. Start when you begin reading; stop when you finish. Save best only when you had a full working solution.
Target for interview: Medium = 20-25 min · Hard = 30-40 min · Best time persists on this device only.

Approach 1 — DFS after each addition ​

O(k · m·n). Too slow for streaming.

Approach 2 — Streaming Union-Find (canonical) ​

Insight. Each new land cell either starts a new island or merges into existing neighbors. Union-Find handles both:

  • Mark cell as land; count++.
  • For each of 4 neighbors that is land AND has a different root: union; count--.
java
List<Integer> numIslands2(int m, int n, int[][] positions) {
    int[] parent = new int[m * n];
    Arrays.fill(parent, -1);
    int[][] D = {{1,0},{-1,0},{0,1},{0,-1}};
    List<Integer> out = new ArrayList<>();
    int count = 0;
    for (int[] p : positions) {
        int r = p[0], c = p[1], id = r * n + c;
        if (parent[id] != -1) { out.add(count); continue; }
        parent[id] = id; count++;
        for (int[] d : D) {
            int nr = r + d[0], nc = c + d[1], nid = nr * n + nc;
            if (nr < 0 || nc < 0 || nr >= m || nc >= n || parent[nid] == -1) continue;
            if (union(parent, id, nid)) count--;
        }
        out.add(count);
    }
    return out;
}
int find(int[] p, int x) { return p[x] == x ? x : (p[x] = find(p, p[x])); }
boolean union(int[] p, int a, int b) {
    int ra = find(p, a), rb = find(p, b);
    if (ra == rb) return false;
    p[ra] = rb; return true;
}
Execution Trace
UF stream — positions=[[0,0],[0,1],[1,2],[2,1]]
step(0,0)0(0,1)1(1,2)2(2,1)3count = 1

Complexity — Time O(k · α(m·n)); Space O(m·n).


Try it yourself ​

Complexity summary ​

ApproachTimeSpaceGrade
DFS per addO(k · m·n)O(m·n)too slow streaming
Union-Find streamingO(k · α(m·n))O(m·n)canonical

When to use which ​

  • Streaming connectivity → Union-Find.
  • Static → DFS/BFS flood fill.
  • Deletion of land → offline reverse: process removals as additions.
✨AI Study CompanionBeta
Was this page helpful?

Released under MIT license.

💡 Quick shortcuts
H HintsR Run JavaA AI Help