Number of Islands - II - Online Queries using DSU - Visualization

Problem Statement

In this problem, you're given a 2D grid of size n × m, initially filled with water (all cells are 0). You are also given k operations where each operation turns a water cell into land (i.e., changes a 0 to 1). After each operation, you must return the number of islands in the grid.

An island is defined as a group of land cells (1s) that are connected horizontally or vertically.

Your task is to simulate each operation in order and return the number of islands after each.

Examples

n m Operators Result Description
3 3 [[0,0], [0,1], [1,2], [2,1]] [1, 1, 2, 3] Each land addition creates a new island (no adjacent land)
3 3 [[0,0], [0,1], [1,1]] [1, 1, 1] All added lands become part of the same connected island
2 2 [[0,0], [0,1], [1,1], [1,0]] [1, 1, 1, 1] Gradual merge into one island
2 2 [[0,0], [0,0], [1,1]] [1, 1, 2] Repeated land on same cell doesn't change island count
1 1 [[0,0]] [1] Single cell island

Solution

Understanding the Problem

We are given a 2D grid of size n x m, where initially all cells are water. Over time, land is added to the grid at specific coordinates through a series of queries. Our goal is to report the number of islands after each land addition.

An island is a group of connected land cells (connected horizontally or vertically). As land is added, some cells may connect to form a larger island, or they may remain isolated.

The challenge lies in efficiently updating and keeping track of the number of islands after each addition, especially as the number of queries can be large.

Step-by-Step Solution with Example

step 1: Flatten the 2D Grid

To simplify union-find operations, we treat the 2D grid as a 1D array. Each cell can be represented as cell_id = row * m + col. This gives a unique index to each cell in the grid.

step 2: Initialize DSU

We create a Disjoint Set Union (DSU) structure, also known as Union-Find, to group connected land cells. Initially, all cells are water, so they are not part of any set.

step 3: Process Each Query

For each land addition query:

  • Convert the 2D coordinates to a 1D cell index.
  • If the cell is already land, skip it (no changes).
  • Otherwise, mark the cell as land and increment the island count.
  • Check its 4 neighbors (up, down, left, right). If a neighbor is land and belongs to a different set, merge the sets using union(). For each merge, decrease the island count by 1 since two separate islands became one.

step 4: Return Island Count After Each Query

After processing each query, record the current island count in the result list.

Example:

Let’s say n = 3, m = 3 and the queries are: [(0,0), (0,1), (1,2), (2,1), (1,1)].

  1. Add (0,0): New land. Count = 1.
  2. Add (0,1): New land. It's adjacent to (0,0), so union them. Count = 1.
  3. Add (1,2): New isolated land. Count = 2.
  4. Add (2,1): New isolated land. Count = 3.
  5. Add (1,1): New land. It's adjacent to (0,1), (1,2), and (2,1). All three are in different sets. Union with all. Count goes from 4 → 3 → 2 → 1.

Edge Cases

  • Adding land to an already land cell: Should be skipped, no effect on count.
  • Adjacent lands already connected: Union will detect they’re in the same set; no change to count.
  • Land added at the borders: Ensure neighbor checks do not go out of bounds.

Finally

This problem is a perfect use case for Disjoint Set Union (DSU). It efficiently maintains groups of connected land cells and helps track how the number of islands evolves over time.

Using optimizations like path compression and union by rank, we can process each query in nearly constant time, making this approach scalable even for large grids and many queries.

Algorithm Steps

  1. Initialize parent and rank arrays for DSU of size n × m.
  2. Initialize a grid of size n × m with all zeros.
  3. For each operator (x, y):
    1. If the cell is already land, skip and append current island count.
    2. Mark cell as land, increase island count by 1.
    3. Check its 4 neighbors. If neighbor is land, perform union:
      1. Find parent of current and neighbor cells.
      2. If different, union them and decrease island count.
    4. Append island count to result array.
  4. Return result array.

Code

C
C++
Python
Java
JS
Go
Rust
Kotlin
Swift
TS
#include <stdio.h>
#include <stdlib.h>

int find(int parent[], int i) {
    if (parent[i] == -1) return i;
    return parent[i] = find(parent, parent[i]);
}

int unionSets(int parent[], int x, int y) {
    int xset = find(parent, x);
    int yset = find(parent, y);
    if (xset != yset) {
        parent[xset] = yset;
        return 1;
    }
    return 0;
}

int* numIslands2(int n, int m, int operators[][2], int k, int* returnSize) {
    int* parent = (int*)malloc(sizeof(int) * n * m);
    for (int i = 0; i < n * m; i++) parent[i] = -1;

    int* grid = (int*)calloc(n * m, sizeof(int));
    int* result = (int*)malloc(sizeof(int) * k);
    int count = 0;
    int directions[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};

    for (int i = 0; i < k; i++) {
        int r = operators[i][0], c = operators[i][1];
        int id = r * m + c;
        if (grid[id] == 1) {
            result[i] = count;
            continue;
        }
        grid[id] = 1;
        count++;
        for (int d = 0; d < 4; d++) {
            int nr = r + directions[d][0], nc = c + directions[d][1];
            int nid = nr * m + nc;
            if (nr >= 0 && nr < n && nc >= 0 && nc < m && grid[nid] == 1) {
                if (unionSets(parent, id, nid)) count--;
            }
        }
        result[i] = count;
    }
    free(parent);
    free(grid);
    *returnSize = k;
    return result;
}

int main() {
    int operators[][2] = {{0,0}, {0,1}, {1,2}, {2,1}};
    int returnSize = 0;
    int* res = numIslands2(3, 3, operators, 4, &returnSize);
    for (int i = 0; i < returnSize; i++) {
        printf("%d ", res[i]);
    }
    printf("\n");
    free(res);
    return 0;
}

Comments

💬 Please keep your comment relevant and respectful. Avoid spamming, offensive language, or posting promotional/backlink content.
All comments are subject to moderation before being published.


Loading comments...