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.
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
Constraints:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j]
is '0'
or '1'
.This problem asks to count the number of islands in a given binary grid where '1' represents land and '0' represents water. Islands are connected horizontally or vertically.
We'll explore three common approaches: Depth-First Search (DFS), Breadth-First Search (BFS), and Union-Find.
This approach recursively explores each connected landmass (island). When a '1' (land) is encountered, a DFS traversal marks all connected '1's as visited by changing them to '0', effectively sinking the island. The count of islands is incremented for each such traversal.
Algorithm:
ans
to 0 (island count).ans
.ans
.The DFS function recursively explores the neighboring cells (up, down, left, right). If a neighbor is land ('1'), it's marked as visited ('0') and the DFS is recursively called on it.
Time Complexity: O(M*N), where M and N are the dimensions of the grid. Each cell is visited at most once.
Space Complexity: O(M*N) in the worst case (a single large island) due to the recursive call stack. Could be reduced to O(N) with iterative DFS.
Similar to DFS, BFS explores connected landmasses. However, instead of recursion, it uses a queue to manage cells to be visited.
Algorithm:
ans
to 0.ans
.ans
.Time Complexity: O(M*N). Each cell is visited at most once.
Space Complexity: O(M*N) in the worst case (a single large island) due to the queue.
This approach uses a disjoint-set data structure (Union-Find) to efficiently group connected land cells.
Algorithm:
p
of size M*N, where each element initially points to itself (representing individual islands).find
function).union
function.The find
function recursively finds the root of a component. The union
function merges two components by setting the parent of one root to the other.
Time Complexity: Amortized O(MNα(M*N)), where α is the inverse Ackermann function (which grows extremely slowly, effectively constant for practical purposes).
Space Complexity: O(M*N) for the parent array.
DFS:
def numIslands(grid):
rows, cols = len(grid), len(grid[0])
def dfs(row, col):
if row < 0 or row >= rows or col < 0 or col >= cols or grid[row][col] == '0':
return
grid[row][col] = '0' # Mark as visited
dfs(row + 1, col)
dfs(row - 1, col)
dfs(row, col + 1)
dfs(row, col - 1)
count = 0
for r in range(rows):
for c in range(cols):
if grid[r][c] == '1':
dfs(r, c)
count += 1
return count
BFS:
from collections import deque
def numIslands(grid):
rows, cols = len(grid), len(grid[0])
count = 0
for r in range(rows):
for c in range(cols):
if grid[r][c] == '1':
count += 1
q = deque([(r, c)])
grid[r][c] = '0'
while q:
row, col = q.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':
q.append((nr, nc))
grid[nr][nc] = '0'
return count
Union-Find:
def numIslands(grid):
rows, cols = len(grid), len(grid[0])
parent = list(range(rows * cols))
def find(i):
if parent[i] == i:
return i
parent[i] = find(parent[i])
return parent[i]
def union(i, j):
root_i = find(i)
root_j = find(j)
if root_i != root_j:
parent[root_i] = root_j
for r in range(rows):
for c in range(cols):
if grid[r][c] == '1':
i = r * cols + c
for dr, dc in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == '1':
j = nr * cols + nc
union(i, j)
return sum(1 for i in range(rows * cols) if parent[i] == i and grid[i // cols][i % cols] == '1')
These examples demonstrate the three approaches. The choice of the best approach depends on the specific requirements and constraints of the problem. For most cases, DFS or BFS are simpler to implement, while Union-Find offers better performance for extremely large grids.