Number of Islands —
A grid is just a graph in disguise.
Every unvisited land cell you find is the seed of a new island — flood-fill outward from it with BFS or DFS, marking every connected land cell visited, and count how many times you had to start a fresh flood fill. It's BFS/DFS with 4 neighbors (up/down/left/right) instead of a graph's adjacency list. Watch the flood fill spread on LearnBug and see each island claimed in turn.
What is the Number of Islands problem?
Given a grid of "1" (land) and "0" (water), count the number of islands — groups of land cells connected horizontally or vertically. Scan every cell; whenever you find unvisited land, that's a brand new island, so flood-fill outward from it to mark the whole connected group visited, then keep scanning.
Why visualization helps
The insight that unlocks this problem is realizing a grid is a graph — each cell is a node, and its 4 neighbors are its edges. LearnBug highlights the flood fill spreading cell by cell and shows exactly when the scan finds a fresh, unvisited land cell that starts a new island — making that graph structure visible on a shape everyone already recognizes.
Everything you already know about graphs, applied to a grid
Cells are nodes, adjacency is edges
Each grid cell connects to up to 4 neighbors (up, down, left, right) — that's the entire "adjacency list," computed from coordinates instead of stored explicitly.
BFS or DFS both work
The flood fill can use either — a queue (BFS) or recursion/stack (DFS). Same result: every connected land cell gets marked in one flood fill.
Counting connected components
This is exactly the "count connected components" pattern — number of provinces, friend circles, and network clusters are the same problem elsewhere.
Islands on a 3×3 grid: [1,1,0] / [0,1,0] / [0,0,1]
Scan hits (0,0) — unvisited land. Start a new island, flood fill outward
This is the first land cell found while scanning row by row. It's unvisited, so it's the seed of island #1. BFS from here spreads to every connected land cell.
Flood fill spreads to (0,1) and (1,1) — both connected to the seed
(0,1) is land and adjacent to (0,0) — visit it, and it in turn connects to (1,1), also land. All three get marked visited as part of the same island.
Scan continues, skips visited/water cells, hits (2,2) — unvisited land
(1,0), (2,0), (2,1) are all water. (2,2) is land and not connected to island #1 (no shared edge with any visited cell), so it starts island #2.
Scan finishes — every cell visited or water
No unvisited land cells remain, so the outer scan loop ends.
Return: 2 islands ✓ [(0,0),(0,1),(1,1)] and [(2,2)]
Grid BFS flood fill
grid = [
["1", "1", "0"],
["0", "1", "0"],
["0", "0", "1"],
]
rows, cols = len(grid), len(grid[0])
visited = set()
def bfs(r, c):
queue = [(r, c)]
visited.add((r, c))
while queue:
row, col = queue.pop(0)
for dr, dc in [(-1,0),(1,0),(0,-1),(0,1)]:
nr, nc = row + dr, col + dc
if (0 <= nr < rows and 0 <= nc < cols
and (nr, nc) not in visited and grid[nr][nc] == "1"):
visited.add((nr, nc))
queue.append((nr, nc))
islands = 0
for r in range(rows):
for c in range(cols):
if grid[r][c] == "1" and (r, c) not in visited:
bfs(r, c) # claims the whole connected island
islands += 1
print(islands)Complexity Notes
Frequently asked questions
Should I use BFS or DFS for the flood fill?
Either works and gives the same island count — this is a "visit every connected node" problem, not a shortest-path problem, so BFS's shortest-path guarantee isn't relevant here. DFS (recursive or with an explicit stack) is often slightly shorter to write; BFS avoids recursion-depth issues on very large islands.
Do I need a separate visited set?
Not necessarily — a common space-saving trick is to overwrite visited land cells directly in the grid (change "1" to "0" once visited), which avoids allocating a separate set entirely. This lesson uses a visited set for clarity, but mutating the grid in place is equally valid and commonly asked about in interviews.
What if diagonal cells should count as connected?
Add the four diagonal direction offsets — (-1,-1), (-1,1), (1,-1), (1,1) — to the neighbor list alongside the four cardinal directions. Everything else about the algorithm stays the same; only the definition of "adjacent" changes.
How does this relate to "number of provinces" or "friend circles"?
Same underlying pattern — counting connected components — just on a different graph representation. Number of Islands uses an implicit grid graph; Number of Provinces typically gives you an explicit adjacency matrix. The flood-fill/count logic is identical.
Watch the flood fill claim each island
Paste your grid BFS/DFS into LearnBug and see every cell visited live.