Skip to main content

01 Matrix

LeetCode 542 | Difficulty: Medium​

Medium

Problem 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.

When to use

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.

When to use

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.

When to use

Grid traversal, island problems, path finding, rotating/transforming matrices.


Solutions​

Solution 1: C# (Best: 380 ms)​

MetricValue
Runtime380 ms
Memory43.5 MB
Date2020-01-01
Solution
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​

ApproachTimeSpace
DP (2D)$O(n Γ— m)$$O(n Γ— m)$
Graph BFS/DFS$O(V + E)$$O(V)$

Interview Tips​

Key Points
  • 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.