🟨 Number of Islands (#200)
🔗 Problem Link
📋 Problem Statement
Given an m x n 2D binary grid grid which represents a map of '1's (land) and '0's (water), return the number of islands.
An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
💡 Examples
Example 1
Input: grid = [
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
Output: 1
Example 2
Input: grid = [
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
Output: 3
🔑 Key Insights & Approach
Core Observation: Use DFS or BFS to mark all connected land cells as visited. Each DFS/BFS call represents one island.
Why DFS/BFS?
- O(m * n) time
- O(min(m, n)) space for BFS, O(m * n) for DFS worst case
- Simple and efficient
Approaches:
- DFS: O(m * n) time, O(m * n) space
- BFS: O(m * n) time, O(min(m, n)) space
- Union-Find: O(m * n) time with path compression
Pattern: "Graph Connected Components" using DFS/BFS.
🐍 Solution: Python
Approach 1: DFS
Time Complexity: O(m * n) | Space Complexity: O(m * n)
from typing import List
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
if not grid:
return 0
rows, cols = len(grid), len(grid[0])
islands = 0
def dfs(r, c):
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 4 directions
dfs(r + 1, c)
dfs(r - 1, c)
dfs(r, c + 1)
dfs(r, c - 1)
for r in range(rows):
for c in range(cols):
if grid[r][c] == '1':
islands += 1
dfs(r, c)
return islands
Approach 2: BFS
Time Complexity: O(m * n) | Space Complexity: O(min(m, n))
from collections import deque
from typing import List
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
if not grid:
return 0
rows, cols = len(grid), len(grid[0])
islands = 0
for r in range(rows):
for c in range(cols):
if grid[r][c] == '1':
islands += 1
queue = deque([(r, c)])
grid[r][c] = '0'
while queue:
row, col = queue.popleft()
for dr, dc in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
nr, nc = row + dr, col + dc
if (0 <= nr < rows and 0 <= nc < cols and
grid[nr][nc] == '1'):
queue.append((nr, nc))
grid[nr][nc] = '0'
return islands
🔵 Solution: Golang
Approach: DFS
Time Complexity: O(m * n) | Space Complexity: O(m * n)
func numIslands(grid [][]byte) int {
if len(grid) == 0 {
return 0
}
rows, cols := len(grid), len(grid[0])
islands := 0
var dfs func(r, c int)
dfs = func(r, c int) {
if r < 0 || r >= rows || c < 0 || c >= cols || 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 r := 0; r < rows; r++ {
for c := 0; c < cols; c++ {
if grid[r][c] == '1' {
islands++
dfs(r, c)
}
}
}
return islands
}