01 Matrix
LeetCode 542 | Difficulty: Mediumβ
MediumProblem Descriptionβ
Given an m x n binary matrix mat, return the distance of the nearest 0 for each cell.
The distance between two cells sharing a common edge is 1.
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,0,0],[0,1,0],[1,1,1]]
Output: [[0,0,0],[0,1,0],[1,2,1]]
Constraints:
- `m == mat.length`
- `n == mat[i].length`
- `1 <= m, n <= 10^4`
- `1 <= m * n <= 10^4`
- `mat[i][j]` is either `0` or `1`.
- There is at least one `0` in `mat`.
Note: This question is the same as 1765: https://leetcode.com/problems/map-of-highest-peak/
Topics: Array, Dynamic Programming, Breadth-First Search, Matrix
Approachβ
Dynamic Programmingβ
Break the problem into overlapping subproblems. Define a state (what information do you need?), a recurrence (how does state[i] depend on smaller states?), and a base case. Consider both top-down (memoization) and bottom-up (tabulation) approaches.
Optimal substructure + overlapping subproblems (counting ways, min/max cost, feasibility).
BFS (Graph/Matrix)β
Use a queue to explore nodes level by level. Start from source node(s), visit all neighbors before moving to the next level. BFS naturally finds shortest paths in unweighted graphs.
Shortest path in unweighted graph, level-order processing, spreading/flood fill.
Matrixβ
Treat the matrix as a 2D grid. Common techniques: directional arrays (dx, dy) for movement, BFS/DFS for connected regions, in-place marking for visited cells, boundary traversal for spiral patterns.
Grid traversal, island problems, path finding, rotating/transforming matrices.
Solutionsβ
Solution 1: C# (Best: 380 ms)β
| Metric | Value |
|---|---|
| Runtime | 380 ms |
| Memory | 43.5 MB |
| Date | 2020-01-01 |
public class Solution {
public int[][] UpdateMatrix(int[][] matrix) {
int m = matrix.GetLength(0);
int n = matrix[0].GetLength(0);
bool[,] visited = new bool[m, n];
Queue<Point> q = new Queue<Point>();
List<int[]> dirs = new List<int[]>()
{
new int[] {1, 0},
new int[] {-1, 0},
new int[] {0, 1},
new int[] {0, -1}
};
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if(matrix[i][j] == 0){
q.Enqueue(new Point(i,j));
visited[i,j] = true;}
}
}
while (q.Count != 0)
{
var top = q.Dequeue();
foreach (var dir in dirs)
{
int xx = top.x + dir[0];
int yy = top.y + dir[1];
if (xx < 0 || xx >= m || yy < 0 || yy >= n || visited[xx, yy])
{
continue;
}
matrix[xx][yy] = matrix[top.x][top.y]+1;
visited[xx, yy] = true;
q.Enqueue(new Point(xx, yy));
}
}
return matrix;
}
}
public class Point
{
public int x { get; }
public int y { get; }
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
}
π 1 more C# submission(s)
Submission (2020-01-01) β 404 ms, 43.6 MBβ
public class Solution {
public int[][] UpdateMatrix(int[][] matrix) {
int m = matrix.GetLength(0);
int n = matrix[0].GetLength(0);
bool[,] visited = new bool[m, n];
Queue<Point> q = new Queue<Point>();
List<int[]> dirs = new List<int[]>()
{
new int[] {1, 0},
new int[] {-1, 0},
new int[] {0, 1},
new int[] {0, -1}
};
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if(matrix[i][j] == 0){
q.Enqueue(new Point(i,j));
visited[i,j] = true;}
}
}
while (q.Count != 0)
{
var top = q.Dequeue();
foreach (var dir in dirs)
{
int xx = top.x + dir[0];
int yy = top.y + dir[1];
if (xx < 0 || xx >= m || yy < 0 || yy >= n || visited[xx, yy])
{
continue;
}
matrix[xx][yy] = matrix[top.x][top.y]+1;
visited[xx, yy] = true;
q.Enqueue(new Point(xx, yy));
}
}
return matrix;
}
}
public class Point
{
public int x { get; }
public int y { get; }
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
}
Complexity Analysisβ
| Approach | Time | Space |
|---|---|---|
| DP (2D) | $O(n Γ m)$ | $O(n Γ m)$ |
| Graph BFS/DFS | $O(V + E)$ | $O(V)$ |
Interview Tipsβ
- Discuss the brute force approach first, then optimize. Explain your thought process.
- Define the DP state clearly. Ask: "What is the minimum information I need to make a decision at each step?"
- Consider if you can reduce space by only keeping the last row/few values.