Given a matrix consists of 0 and 1, find the distance to the nearest 0 for each cell.
The distance between two adjacent cells is 1.
Example 1:
Input: [[0,0,0], [0,1,0], [0,0,0]] Output: [[0,0,0], [0,1,0], [0,0,0]]
Example 2:
Input: [[0,0,0], [0,1,0], [1,1,1]] Output: [[0,0,0], [0,1,0], [1,2,1]]
Note:
The core challenge of this problem is to efficiently compute the shortest distance from each cell to the nearest cell containing a 0. This problem is significant in various applications such as image processing, pathfinding in grids, and more. A common pitfall is to use a brute-force approach, which can be highly inefficient for larger matrices.
To solve this problem, we can use a Breadth-First Search (BFS) approach. BFS is ideal for finding the shortest path in an unweighted grid. Here's a step-by-step approach:
A naive solution would involve iterating over each cell and performing a BFS or DFS to find the nearest 0. This approach is not optimal as it results in a time complexity of O((m*n)^2), where m and n are the dimensions of the matrix.
We can optimize the solution by performing a multi-source BFS. The idea is to start the BFS from all 0s simultaneously. This way, we can propagate the distance to all 1s in the matrix efficiently.
Here is a step-by-step breakdown of the optimized algorithm:
import collections
def updateMatrix(matrix):
# Get the dimensions of the matrix
rows, cols = len(matrix), len(matrix[0])
# Initialize the distance matrix with infinity
dist = [[float('inf')] * cols for _ in range(rows)]
# Initialize the queue for BFS
queue = collections.deque()
# Enqueue all cells containing 0 and set their distance to 0
for r in range(rows):
for c in range(cols):
if matrix[r][c] == 0:
dist[r][c] = 0
queue.append((r, c))
# Directions for moving up, down, left, and right
directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
# Perform BFS
while queue:
r, c = queue.popleft()
# Check all four directions
for dr, dc in directions:
nr, nc = r + dr, c + dc
# If the new cell is within bounds and we found a shorter path
if 0 <= nr < rows and 0 <= nc < cols and dist[nr][nc] > dist[r][c] + 1:
dist[nr][nc] = dist[r][c] + 1
queue.append((nr, nc))
return dist
The time complexity of the optimized solution is O(m*n) because each cell is enqueued and dequeued at most once. The space complexity is also O(m*n) due to the distance matrix and the queue.
Potential edge cases include:
Each of these cases is handled by the BFS approach, ensuring correct distance calculations.
To test the solution comprehensively, consider the following test cases:
def test_updateMatrix():
assert updateMatrix([[0,0,0],[0,1,0],[0,0,0]]) == [[0,0,0],[0,1,0],[0,0,0]]
assert updateMatrix([[0,0,0],[0,1,0],[1,1,1]]) == [[0,0,0],[0,1,0],[1,2,1]]
assert updateMatrix([[1,1,1],[1,0,1],[1,1,1]]) == [[1,1,1],[1,0,1],[1,1,1]]
assert updateMatrix([[0]]) == [[0]]
assert updateMatrix([[1]]) == [[float('inf')]] # Assuming no 0s in the matrix
test_updateMatrix()
When approaching such problems, consider the following tips:
In this blog post, we discussed the 01 Matrix problem, explored a naive and an optimized solution, and provided a detailed explanation of the BFS approach. Understanding and solving such problems is crucial for developing strong algorithmic thinking and problem-solving skills.
For further reading and practice, consider the following resources: