← Visualizers
Graphs · Flood fill on a grid — the inversion LeetCode 130

Surrounded Regions / visualized

You cannot mark a cell enclosed. Enclosure is a property of a whole region, and it is only ever falsified — the moment a walk steps off the edge — never confirmed until the walk is over. Its complement is confirmable from one cell: an O on the border escapes, full stop. So invert the question. Seed the border, flood-mark everything that escapes, then flip whatever the mark did not reach.

Execution

idle
INVARIANT Boundary Inversion: Never test "is this region surrounded?" (requires exploring entire component). Test the complement: "can it reach the border?" An 'O' on the border escapes by definition.
Press Run to begin.
0 / 0
Speed

Java · running line

wall — X from start current cell in the queue marked — it escapes captured — flipped to X
INTERVIEW SCRIPT

How to Explain Surrounded Regions to an Interviewer

1. Invert the Enclosure Check

"Searching from the inside to see if a region touches the boundary requires buffering all visited cells and a global boolean flag. Instead, invert the question: any 'O' on the border escapes."

2. Phase 1: Border Flooding to '#'

"Walk the 4 boundaries. Whenever board[r][c] == 'O', launch BFS/DFS and mark all reachable cells with temporary sentinel '#'."

3. Phase 2: Flipping and Restoring

"Iterate through the whole grid: any cell still reading 'O' was truly captured and flips to 'X'. Any cell reading '#' was border-connected and restores to 'O'."

4. Complexity Mastery

"Every cell is touched a constant number of times. Total time is $O(m \cdot n)$ and auxiliary space is $O(m \cdot n)$ for recursion stack or queue."

O(m·n) time · O(m·n) for the queue  ·  the one-pass version — walk each region, remember whether it touched the border, then decide — needs a per-region list to go back and repaint, and a flag threaded through the recursion. The complement needs neither: an O on the border is known to escape from that one cell, with no region to assemble. Same O(m·n) work, none of the bookkeeping. The temporary # is the only price, and the third pass erases it.