01 Matrix
Given an m x n binary matrix mat, return the distance of the nearest 0 for each cell, where the distance between two adjacent cells is 1. Seed the queue with every 0 at once — this is multi-source breadth-first search , so the ring that first reaches a cell always belongs to that cell's nearest 0, not just one particular 0.
Constraints
- m == mat.length
- n == mati.length
- 1 ≤ m, n ≤ 104
- 1 ≤ m * n ≤ 104
- mati[j] is 0 or 1
- There is at least one 0 in mat
Example
mat = [[0, 0, 0], [0, 1, 0], [1, 1, 1]][[0, 0, 0], [0, 1, 0], [1, 2, 1]]Explanation The bottom row is at distance 1 or 2 from the nearest 0 in the top two rows.
In plain terms
- Multi-source
- Starting the search from several places at the same time, instead of just one, so they all expand outward together.
One cell per matrix cell, row by row — each shows its distance to the nearest 0
Seed the queue with every 0 at once — in this matrix that is (0,0) and (0,1), both at distance 0.
What happens in this step
mat = [[0,0,1],[1,1,1]] queue = [(0,0),(0,1)] both at dist = 0 Every 0 cell is a source and enters the queue in the same first pass — that's multi-source BFS. The four 1 cells have no distance yet, so their slots show —.
Steps to visualize
- This walkthrough uses a smaller matrix than the example above so the whole thing fits in one row: mat = [[0, 0, 1], [1, 1, 1]].
- The row has one slot per matrix cell, read left to right then down. A slot shows — until a distance has been worked out for it.
- Mark every 0 as distance 0 and enqueue all of them at once.
- Dequeue a cell; for each neighbor that hasn't been assigned a distance yet, set it to this cell's distance + 1 and enqueue it.
- Repeat until the queue is empty — every cell now holds its distance to the nearest 0.
Walk through the code
Same walkthrough, now with the code. Press Next to move one step and watch which lines run.
Seed the queue with every 0 at once — in this matrix that is (0,0) and (0,1), both at distance 0.
What happens in this step
mat = [[0,0,1],[1,1,1]] queue = [(0,0),(0,1)] both at dist = 0 Every 0 cell is a source and enters the queue in the same first pass — that's multi-source BFS. The four 1 cells have no distance yet, so their slots show —.
Solution
function updateMatrix(mat) {
const rows = mat.length;
const cols = mat[0].length;
const dist = mat.map((row) => row.map(() => -1));
const queue = [];
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
if (mat[r][c] === 0) {
dist[r][c] = 0;
queue.push([r, c]);
}
}
}
const dirs = [[1, 0], [-1, 0], [0, 1], [0, -1]];
while (queue.length > 0) {
const [r, c] = queue.shift();
for (const [dr, dc] of dirs) {
const nr = r + dr;
const nc = c + dc;
if (nr >= 0 && nr < rows && nc >= 0 && nc < cols && dist[nr][nc] === -1) {
dist[nr][nc] = dist[r][c] + 1;
queue.push([nr, nc]);
}
}
}
return dist;
}- Time
- O(m * n)
- Space
- O(m * n)
Test cases
| Input | Expected | Covers |
|---|---|---|
mat = [[0, 0, 0], [0, 1, 0], [1, 1, 1]] | [[0, 0, 0], [0, 1, 0], [1, 2, 1]] | example from the docstring |
mat = [[0, 0], [0, 0]] | [[0, 0], [0, 0]] | every cell is already a 0 |
mat = [[0]] | [[0]] | smallest valid input, a single 0 |
mat = [[0, 1, 1, 1, 0]] | [[0, 1, 2, 1, 0]] | a cell equidistant from two different 0s |
mat = [[0, 1], [1, 0]] | [[0, 1], [1, 0]] | every 1 is directly adjacent to a 0 |
mat = [[0, 1, 1, 1, 1]] | [[0, 1, 2, 3, 4]] | only one 0, distances grow all the way across |
mat = [[0], [1], [1]] | [[0], [1], [2]] | a single-column grid |