AlgoMaster Logo

Number of Islands II

hardFrequencyUpdated September 21, 2026

Understanding the Problem

This is the dynamic version of the classic "Number of Islands" problem. In the original problem (LeetCode #200), you get a fixed grid and count connected components of land cells. Here, the grid starts empty and land cells are added one at a time. After each addition, we report the current island count.

The challenge is doing this efficiently. Each time we add a land cell, only its four neighbors can change connectivity, so rerunning a full BFS or DFS over the whole grid after every addition wastes work. When the new cell touches an existing island, it joins that island. When it touches two or more separate islands at once, those islands merge into one and the total count drops. We need a structure that handles these incremental merges without rescanning everything.

Union Find (Disjoint Set Union) matches this shape directly. It groups elements dynamically and answers whether two elements are in the same group, which is what tracking islands as land arrives requires.

Key Constraints:

  • 1 <= m, n <= 10^4 -> The grid can be up to 10^4 x 10^4 = 10^8 cells, too large to allocate as a full m x n array. We work only with the cells that become land, of which there are at most 10^4.
  • 1 <= positions.length <= 10^4 -> At most 10,000 addLand operations. To keep the total cost manageable, each operation needs to be close to O(1).
  • 0 <= r_i < m, 0 <= c_i < n -> Positions are always within bounds, but duplicates are allowed: a position may repeat, meaning we add land to a cell that is already land. The count must not change on a duplicate.

Approach 1: BFS/DFS After Each Operation

Intuition

Treat each operation as a fresh "Number of Islands" problem. Maintain a grid, and after each addLand, run a full BFS over the entire grid to count connected components from scratch.

For each addLand, mark the cell as land, then iterate over the grid. Every time you find an unvisited land cell, start a BFS to mark all connected land cells as visited, and increment the island count.

Algorithm

  1. Create an m x n grid initialized to all water (0).
  2. For each position in positions:
    • Mark grid[r][c] = 1 (land).
    • Run a full BFS/DFS over the grid to count connected components.
    • Append the count to the result.
  3. Return the result array.

Visualization and Code

Loading animation...

With k up to 10^4 and the grid up to 10^8 cells, O(k m n) is far too slow, and allocating the full grid is not even possible at the upper bound. The next approach keeps the connectivity information between operations instead of rebuilding it, updating only what the new cell affects.

Approach 2: Union Find (Optimal)

Intuition

Maintain a running island count and update it as each cell arrives. When we add a new land cell, it starts as its own island, so the count goes up by 1. Then we check the four neighbors. For each neighbor that is already land and sits in a different island, we union the two and decrement the count by 1. After processing all four neighbors, the count is the answer for this operation.

Union Find supports two operations: find(x) returns the representative of x's group, and union(x, y) merges two groups. With path compression in find and union by rank, both run in nearly O(1) amortized time, measured as O(alpha(mn)) where alpha is the inverse Ackermann function.

The grid can hold up to 10^8 cells but at most 10^4 become land, so we store the parent and rank in a HashMap keyed only by land cells instead of allocating a full array. Each 2D coordinate maps to a single integer key with row * n + col, which is unique because every column index is less than n.

Algorithm

  1. Initialize an empty HashMap parent, an empty HashMap rank, and count = 0.
  2. For each position (r, c) in positions:
    • Compute the unique key id = r * n + c.
    • If id is already in parent (duplicate addLand), append the current count and skip.
    • Otherwise, add id to parent with parent[id] = id (self-root), set rank[id] = 0, and increment count.
    • Check all 4 neighbors (nr, nc). For each neighbor that is already land (exists in parent):
      • Find the root of the current cell and the root of the neighbor.
      • If they have different roots, union them and decrement count.
    • Append count to the result.
  3. Return the result array.

Visualization and Code

Loading animation...