Skip to content

Number of Islands

Given an m x n 2D binary grid grid where '1' represents land and '0' represents water, return the number of islands.

An island is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are surrounded by water.

GridOutputExplanation
[["1","1","1","1","0"],["1","1","0","1","0"],["1","1","0","0","0"],["0","0","0","0","0"]]1All four 1s are connected, forming one island
[["1","1","0","0","0"],["1","1","0","0","0"],["0","0","1","0","0"],["0","0","0","1","1"]]3Three separate islands
  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 300
  • grid[i][j] is '0' or '1'
ApproachTimeSpaceNotes
DFS (Recursive)O(m * n)O(m * n)Call stack depth in worst case, intuitive
BFS (Queue-based)O(m * n)O(m * n)Explicit queue, iterative traversal

* m = rows, n = columns

  • Pick DFS if you want the most straightforward, recursive solution.
  • Pick BFS if you prefer an iterative approach with explicit queue management.
Most Intuitive
DFS (Recursive)
O(m * n) time · O(m * n) space
Iterative
BFS (Queue)
O(m * n) time · O(m * n) space
Section titled “Approach 1: DFS (Depth-First Search) — Recommended”
★ Recommended

Use recursive DFS to explore each island completely before moving to the next unvisited land cell. Mark visited cells to avoid counting them multiple times.

⏱ Time O(m * n) Visit each cell once 💾 Space O(m * n) Recursion stack + grid marking

Input: grid = [["1","1","0"],["0","1","0"],["1","0","1"]]

Step 1: Scan grid, find "1" at (0, 0)
Step 2: DFS from (0, 0) → marks (0, 0), (0, 1), (1, 1) as visited → Count = 1
Step 3: Continue scan, find "1" at (2, 0)
Step 4: DFS from (2, 0) → marks (2, 0) → Count = 2
Step 5: Continue scan, find "1" at (2, 2)
Step 6: DFS from (2, 2) → marks (2, 2) → Count = 3
Result: 3 islands
function numIslandsDFS(grid):
if grid is empty:
return 0
count = 0
for i from 0 to rows - 1:
for j from 0 to cols - 1:
if grid[i][j] == '1':
dfs(grid, i, j)
count += 1
return count
function dfs(grid, i, j):
if i < 0 or i >= rows or j < 0 or j >= cols or grid[i][j] == '0':
return
grid[i][j] = '0' // Mark as visited
dfs(grid, i + 1, j)
dfs(grid, i - 1, j)
dfs(grid, i, j + 1)
dfs(grid, i, j - 1)
number_of_islands_dfs.py
def num_islands_dfs(grid: list[list[str]]) -> int:
"""
DFS approach - recursively explore each island from any land cell.
Time: O(m * n) - visit each cell once
Space: O(m * n) - recursion call stack in worst case
"""
if not grid or not grid[0]:
return 0
rows, cols = len(grid), len(grid[0])
count = 0
def dfs(r: int, c: int) -> None:
"""Mark all connected land cells as visited."""
if r < 0 or r >= rows or c < 0 or c >= cols or grid[r][c] == '0':
return
grid[r][c] = '0' # Mark as visited
# Explore all 4 directions
dfs(r + 1, c) # Down
dfs(r - 1, c) # Up
dfs(r, c + 1) # Right
dfs(r, c - 1) # Left
# Find and count islands
for i in range(rows):
for j in range(cols):
if grid[i][j] == '1':
dfs(i, j)
count += 1
return count
# Test cases
grid1 = [["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]]
print(num_islands_dfs(grid1)) # 1
grid2 = [["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]]
print(num_islands_dfs(grid2)) # 3
✓ Simple

Use a queue-based BFS to explore each island level by level. Mark cells as visited when they are enqueued to avoid duplicate processing.

⏱ Time O(m * n) Visit each cell once 💾 Space O(m * n) Queue storage + grid marking

Input: grid = [["1","1","0"],["0","1","0"],["1","0","1"]]

Step 1: Scan grid, find "1" at (0, 0)
Step 2: BFS from (0, 0) using queue → processes (0, 0), (0, 1), (1, 1) → Count = 1
Step 3: Continue scan, find "1" at (2, 0)
Step 4: BFS from (2, 0) using queue → processes (2, 0) → Count = 2
Step 5: Continue scan, find "1" at (2, 2)
Step 6: BFS from (2, 2) using queue → processes (2, 2) → Count = 3
Result: 3 islands
function numIslandsBFS(grid):
if grid is empty:
return 0
count = 0
for i from 0 to rows - 1:
for j from 0 to cols - 1:
if grid[i][j] == '1':
bfs(grid, i, j)
count += 1
return count
function bfs(grid, i, j):
queue = [(i, j)]
grid[i][j] = '0' // Mark as visited
while queue is not empty:
row, col = queue.dequeue()
for each direction (up, down, left, right):
newRow, newCol = row + dr, col + dc
if valid(newRow, newCol) and grid[newRow][newCol] == '1':
grid[newRow][newCol] = '0' // Mark as visited
queue.enqueue((newRow, newCol))
number_of_islands_bfs.py
from collections import deque
def num_islands_bfs(grid: list[list[str]]) -> int:
"""
BFS approach - use queue to explore each island level by level.
Time: O(m * n) - visit each cell once
Space: O(m * n) - queue storage
"""
if not grid or not grid[0]:
return 0
rows, cols = len(grid), len(grid[0])
count = 0
def bfs(start_r: int, start_c: int) -> None:
"""Mark all connected land cells as visited using BFS."""
queue = deque([(start_r, start_c)])
grid[start_r][start_c] = '0' # Mark as visited
while queue:
r, c = queue.popleft()
# Explore all 4 directions
for dr, dc in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == '1':
grid[nr][nc] = '0' # Mark as visited
queue.append((nr, nc))
# Find and count islands
for i in range(rows):
for j in range(cols):
if grid[i][j] == '1':
bfs(i, j)
count += 1
return count
# Test cases
grid1 = [["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]]
print(num_islands_bfs(grid1)) # 1
grid2 = [["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]]
print(num_islands_bfs(grid2)) # 3