Number of Islands

MediumGraphs · DFS Flood Fill🧩 Graph DFSLeetCode #200 ↗Updated

Problem

You get an m × n grid of characters where '1' is land and '0' is water. Land cells that touch horizontally or vertically belong to the same island; everything outside the grid is water. Return how many separate islands there are.
Inputrows: 11000 / 11000 / 00100 / 00011Output3
Inputrows: 111 / 010 / 111Output1

1 ≤ m, n ≤ 300  ·  grid[i][j] is '0' or '1'  ·  diagonal cells are not connected

Try it yourself

Java
class Solution {
    public int numIslands(char[][] grid) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
An island is just a connected component of land. Scan the grid; each time you hit unvisited land, count one island and sink (flood-fill) the whole component so it is never counted again.
PatternGraph DFS

Instinct Connected regions, all paths, reachability, cloning or 2-colouring a graph or grid: dive from a node, mark it, recurse into unvisited neighbours.

Memory hack Mark before you march: go deep, paint as you go, and back up only when every door is already painted.

Open the Graph DFS guide →

Approaches

Brute ForceFlood Each Cell, Count Island Leaders

Time O((m·n)2)Space O(m·n)

For every land cell, BFS its whole island with a fresh visited array and count the cell only if it is the island's leader (smallest index r*n+c). Each island has exactly one leader, but one island of k cells is explored k times.

Java
public int numIslands(char[][] grid) {
    int m = grid.length, n = grid[0].length, count = 0;
    int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    for (int s = 0; s < m * n; s++) {
        if (grid[s / n][s % n] != '1') continue;
        boolean[] seen = new boolean[m * n]; // fresh for every start cell
        Deque<Integer> q = new ArrayDeque<>(List.of(s));
        seen[s] = true;
        boolean leader = true; // is s the smallest id in its island?
        while (!q.isEmpty() && leader) {
            int cur = q.poll(), r = cur / n, c = cur % n;
            if (cur < s) leader = false;
            for (int[] d : dirs) {
                int x = r + d[0], y = c + d[1];
                if (x < 0 || y < 0 || x >= m || y >= n || grid[x][y] != '1') continue;
                if (!seen[x * n + y]) { seen[x * n + y] = true; q.add(x * n + y); }
            }
        }
        if (leader) count++;
    }
    return count;
}

Correct and read-only, but re-explores every island once per cell — quadratic.

At a glance

LevelApproachTimeSpace
Brute ForceFlood Each Cell, Count Island LeadersO((m·n)2)O(m·n)
BetterUnion-Find (Disjoint Set Union)O(m·n·α(m·n))O(m·n)
OptimalDFS Flood Fill (Sink the Island)O(m·n)O(m·n) stack
Common pitfalls
  • BFS: mark on enqueue, not dequeue, or cells repeat.
  • Diagonals do not connect — use 4 directions.
  • Compare with '1' (char), not 1.
Interview tips
  • Ask if mutating the grid is allowed; else use visited.
  • Frame it as “count connected components”.
  • Land added over time (LC 305)? → Union-Find.
Pattern
Grid flood fill → count or label connected groups of similar cells.
My notes saved in this browser