01 Matrix - Python Solution and Time Complexity Analysis
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 number of elements of the given matrix will not exceed 10,000.
- There are at least one 0 in the given matrix.
- The cells are adjacent in only four directions: up, down, left and right.
Understanding the Problem
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.
Approach
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:
Naive Solution
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.
Optimized Solution
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.
Algorithm
Here is a step-by-step breakdown of the optimized algorithm:
- Initialize a queue and enqueue all cells containing 0.
- Initialize a distance matrix with infinity for all cells except those containing 0 (set to 0).
- Perform BFS from all 0s, updating the distance for each cell based on its neighbors.
Code Implementation
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
Complexity Analysis
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.
Edge Cases
Potential edge cases include:
- A matrix with all 0s.
- A matrix with all 1s except one 0.
- Single row or single column matrices.
Each of these cases is handled by the BFS approach, ensuring correct distance calculations.
Testing
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()
Thinking and Problem-Solving Tips
When approaching such problems, consider the following tips:
- Understand the problem constraints and edge cases.
- Think about the most efficient data structures and algorithms (e.g., BFS for shortest path problems).
- Break down the problem into smaller, manageable parts.
- Practice similar problems to improve problem-solving skills.
Conclusion
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.
Additional Resources
For further reading and practice, consider the following resources: