2Brute2Best
🔥0
01

Flood fill / islands (Graph BFS / DFS Sub-pattern)

Find, count, measure or repaint the connected regions of a grid.

Signals in the problem statement
  • ›

    "island", "region", "connected 4-directionally"

  • ›

    "number of …" / "largest …" / "paint all connected cells"

  • ›

    "surrounded by", "can't reach the border", "flows to the ocean"

What makes it different

Flood Fill repaints the one region around a given cell (watch out when the new colour equals the old one). Number of Islands counts how many DFS starts the scan needs, and Max Area makes the DFS return the size. Number of Enclaves and Surrounded Regions reverse the question: flood from the border first, then whatever is left is the answer. Pacific Atlantic floods uphill from each ocean and keeps the cells both floods reach.

Questions

ordered from “learn the idea” to “recognise it without help”
  1. 1
    Flood Fill
    Basic Anchor·LeetCode #733
    Easy
  2. 2
    Number of Islands
    Basic Reinforcement·LeetCode #200
    Medium
  3. 3
    Max Area of Island
    Slight Variation·LeetCode #695
    Medium
  4. 4
    Number of Enclaves
    Medium·LeetCode #1020
    Medium
  5. 5
    Surrounded Regions
    Pattern Transfer·LeetCode #130
    Medium
  6. 6
    Pacific Atlantic Water Flow
    Interview-Level·LeetCode #417
    Medium

Template

flood-fill-template.cpp
// Flood fill: every unvisited land cell starts one DFS; everything it reaches is one island.
int dr[4] = {1, -1, 0, 0}, dc[4] = {0, 0, 1, -1};

int sink(vector<vector<char>>& grid, int r, int c) {
    int R = grid.size(), C = grid[0].size();
    if (r < 0 || c < 0 || r >= R || c >= C || grid[r][c] != '1') return 0;
    grid[r][c] = '0';                             // mark BEFORE exploring, so no cell is counted twice
    int size = 1;
    for (int d = 0; d < 4; d++) size += sink(grid, r + dr[d], c + dc[d]);
    return size;                                  // island size (Max Area); ignore it to just count
}

int countIslands(vector<vector<char>>& grid) {
    int islands = 0;
    for (int r = 0; r < (int)grid.size(); r++)
        for (int c = 0; c < (int)grid[0].size(); c++)
            if (grid[r][c] == '1') { islands++; sink(grid, r, c); }
    return islands;
}
Remember this · Graph BFS / DFS
Trigger
Grid of cells, islands, regions, "minimum steps", transformations between states, connected components.
Think
What is a node, what is an edge, and do I need the shortest path or just reachability?
Key question
How do I mark visited so I never process a node twice?