Learn how to solve the “01 Matrix” problem (LeetCode 542) by using a multi-source breadth-first search. We walk through the Python code, explain each step, run a dry example, and analyze complexity.
What the Problem Asks
LeetCode 542: 01 Matrix
Given anm x n
binary matrixmat
of0
s and1
s, return a matrixdist
wheredist[i][j]
is the distance of the nearest0
to cell(i, j)
. Distance is measured in number of steps moving vertically or horizontally.
Input:
mat
: 2D list of integers0
or1
.
Output:
- 2D list
distance
of same shape, where each cell holds the minimum distance to any0
inmat
Intuition & Approach
- Multi-Source BFS:
- Instead of running BFS from every
1
cell (which would be slow), we enqueue all0
cells initially. - Then we expand outward in waves. The first time we reach a
1
, its distance is the BFS level at which we discover it.
- Instead of running BFS from every
- Why It Works:
- BFS guarantees that when a cell is first visited, it’s via the shortest path from any source—in this case, the nearest
0
.
- BFS guarantees that when a cell is first visited, it’s via the shortest path from any source—in this case, the nearest
- High-Level Steps:
- Initialize
distance
andvisited
arrays (both zeros). - Enqueue every
(r, c, dist=0)
for whichmat[r][c] == 0
and mark visited. - While the queue isn’t empty:
- Pop
(i, j, d)
, setdistance[i][j] = d
. - For each neighbor
(ni, nj)
in four directions:- If it’s in bounds and unvisited, enqueue
(ni, nj, d+1)
and mark visited.
- If it’s in bounds and unvisited, enqueue
- Pop
- Return
distance
.
- Initialize
Code Implementation
from collections import deque
from typing import List
class Solution:
def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:
rows, cols = len(mat), len(mat[0])
visited = [[0]*cols for _ in range(rows)]
distance = [[0]*cols for _ in range(rows)]
queue = deque()
# 1. Enqueue all zeros as BFS sources
for r in range(rows):
for c in range(cols):
if mat[r][c] == 0:
queue.append((r, c, 0))
visited[r][c] = 1
# 2. BFS from all zeros simultaneously
while queue:
i, j, d = queue.popleft()
distance[i][j] = d
# Visit four directions
for di, dj in [(-1,0),(1,0),(0,-1),(0,1)]:
ni, nj = i + di, j + dj
# Skip out of bounds or already visited
if (0 <= ni < rows and 0 <= nj < cols
and visited[ni][nj] == 0):
visited[ni][nj] = 1
queue.append((ni, nj, d+1))
return distance
Step-by-Step Explanation
- Initialization:
visited[r][c]
tracks which cells have been enqueued.distance[r][c]
will hold the answer for each cell.queue
is seeded with all(r, c, 0)
wheremat[r][c] == 0
.
- Multi-Source BFS:
- Each dequeued tuple gives us
(i, j)
plus its distanced
from the nearest zero. - We record
distance[i][j] = d
. - For each neighbor
(ni, nj)
, if it’s in bounds and not yet visited, we enqueue(ni, nj, d+1)
—one step farther from a zero.
- Each dequeued tuple gives us
- Completion:
- When BFS finishes, every cell’s shortest distance to some zero has been set.
Dry Run Example
mat = [
[0,1,1],
[1,1,1],
[1,1,0]
]
- Enqueue zeros:
(0,0,0)
and(2,2,0)
. - BFS Level 0:
- Dequeue
(0,0,0)
, setdist[0][0]=0
, enqueue its unvisited neighbors(1,0,1)
and(0,1,1)
. - Dequeue
(2,2,0)
, setdist[2][2]=0
, enqueue(1,2,1)
and(2,1,1)
.
- Dequeue
- BFS Level 1:
- Process
(1,0,1)
,(0,1,1)
,(1,2,1)
,(2,1,1)
—set distances to 1 and enqueue their fresh neighbors withd=2
.
- Process
- BFS Level 2:
- Remaining cell
(1,1,2)
gets distance 2.
- Remaining cell
- Result: csharpCopy
[ [0,1,2], [1,2,1], [2,1,0] ]
Time & Space Complexity
- Time Complexity: O(m·n)
- Each cell is enqueued and processed at most once.
- Space Complexity: O(m·n)
- The
visited
anddistance
arrays plus the BFS queue may all hold O(m·n) elements in the worst case.
- The
Conclusion
By turning every zero into a BFS source and expanding outward, we compute every cell’s distance to the nearest zero in optimal linear time. This “multi-source BFS” pattern is a powerful tool for any grid problem that asks for nearest distances to a set of starting points. Happy coding!
For any changes to the article, kindly email at code@codeanddebug.in or contact us at +91-9712928220.