DFS Flood Fill
Intuition
We iterate through every cell in the grid. When we find a land cell '1' that hasn't been visited yet, we've discovered a new island. We then run DFS from that cell to mark all connected land cells as visited (by changing them to '0'), effectively "sinking" the entire island. Each time we trigger a new DFS, we increment our island count. This flood-fill approach is intuitive because it mirrors how we'd visually identify islands -- find a piece of land, trace its entire boundary, then look for the next one.
Algorithm
- Initialize an island counter to 0.
- Iterate through each cell in the grid.
- When a cell with value `'1'` is found, increment the island counter.
- Run DFS from that cell: mark it as `'0'` (visited), then recursively visit all four adjacent cells that contain `'1'`.
- After the DFS completes, all land in this island has been marked. Continue scanning for the next unvisited `'1'`.
- Return the island counter.
O(m * n) where m and n are the dimensions of the gridSpaceO(m * n) for the recursion stack in the worst caseCode (C++ · Java · Python · Go)
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
int m = grid.size(), n = grid[0].size();
int count = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
count++;
dfs(grid, i, j);
}
}
}
return count;
}
private:
void dfs(vector<vector<char>>& grid, int r, int c) {
int m = grid.size(), n = grid[0].size();
if (r < 0 || r >= m || c < 0 || c >= n || grid[r][c] == '0') return;
grid[r][c] = '0';
dfs(grid, r + 1, c);
dfs(grid, r - 1, c);
dfs(grid, r, c + 1);
dfs(grid, r, c - 1);
}
};class Solution {
public int numIslands(char[][] grid) {
int m = grid.length, n = grid[0].length;
int count = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
count++;
dfs(grid, i, j);
}
}
}
return count;
}
private void dfs(char[][] grid, int r, int c) {
int m = grid.length, n = grid[0].length;
if (r < 0 || r >= m || c < 0 || c >= n || grid[r][c] == '0') return;
grid[r][c] = '0';
dfs(grid, r + 1, c);
dfs(grid, r - 1, c);
dfs(grid, r, c + 1);
dfs(grid, r, c - 1);
}
}from typing import List
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
m, n = len(grid), len(grid[0])
count = 0
def dfs(r, c):
if r < 0 or r >= m or c < 0 or c >= n or grid[r][c] == '0':
return
grid[r][c] = '0'
dfs(r + 1, c)
dfs(r - 1, c)
dfs(r, c + 1)
dfs(r, c - 1)
for i in range(m):
for j in range(n):
if grid[i][j] == '1':
count += 1
dfs(i, j)
return countfunc numIslands(grid [][]byte) int {
m, n := len(grid), len(grid[0])
count := 0
var dfs func(r, c int)
dfs = func(r, c int) {
if r < 0 || r >= m || c < 0 || c >= n || grid[r][c] == '0' {
return
}
grid[r][c] = '0'
dfs(r+1, c)
dfs(r-1, c)
dfs(r, c+1)
dfs(r, c-1)
}
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if grid[i][j] == '1' {
count++
dfs(i, j)
}
}
}
return count
}