01 Matrix medium
Problem Statement
Given an m x n
binary matrix mat
, return the distance of the nearest 0 for each cell.
The distance between two cells (r1, c1) and (r2, c2) is |r1 - r2| + |c1 - c2|.
Example 1
Input: mat = [[0,0,0],[0,1,0],[0,0,0]]
Output: [[0,0,0],[0,1,0],[0,0,0]]
Example 2
Input: mat = [[0,1,0],[1,1,1],[0,1,0]]
Output: [[0,1,0],[1,2,1],[0,1,0]]
Steps
-
Initialization: Create a result matrix
dist
of the same size asmat
, filled with infinity (a large value). For cells containing 0 inmat
, set the corresponding value indist
to 0. -
Multi-source BFS: Perform a Breadth-First Search (BFS) starting from all cells containing 0. Use a queue to store the coordinates of cells to visit. Initially, add all (r,c) coordinates where
mat[r][c] == 0
to the queue. -
Iteration: While the queue is not empty:
- Dequeue a cell (r,c).
- Explore its four neighbors (up, down, left, right).
- For each neighbor (nr, nc):
- If
dist[nr][nc]
is still infinity (meaning it hasn't been visited), updatedist[nr][nc]
todist[r,c] + 1
(distance from nearest 0) and enqueue (nr,nc).
- If
-
Return: Return the
dist
matrix.
Explanation
The solution uses a multi-source Breadth-First Search (BFS) to efficiently find the shortest distance from each cell to the nearest 0. Starting from all 0s simultaneously, the BFS explores the matrix layer by layer, updating the distances in the dist
matrix. This approach guarantees that the first time a cell is reached, it's reached by the shortest path from a 0. Using infinity as an initial value ensures that cells further away from zeros are correctly updated later.
Code
import collections
def updateMatrix(mat):
"""
Finds the distance of the nearest 0 for each cell in a binary matrix.
Args:
mat: The input binary matrix (list of lists).
Returns:
The distance matrix (list of lists).
"""
m, n = len(mat), len(mat[0])
dist = [[float('inf')] * n for _ in range(m)]
# Initialize distances for cells containing 0
queue = collections.deque()
for r in range(m):
for c in range(n):
if mat[r][c] == 0:
dist[r][c] = 0
queue.append((r, c))
# BFS
while queue:
r, c = queue.popleft()
for dr, dc in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
nr, nc = r + dr, c + dc
if 0 <= nr < m and 0 <= nc < n and dist[nr][nc] == float('inf'):
dist[nr][nc] = dist[r][c] + 1
queue.append((nr, nc))
return dist
Complexity
- Time Complexity: O(M*N), where M and N are the dimensions of the matrix. This is because each cell is visited and processed at most once during the BFS.
- Space Complexity: O(M*N) in the worst case, to store the
dist
matrix and the queue. In the best case the queue's size will be the number of zeros.