💡 This approach improves efficiency by starting BFS simultaneously from all zero cells, spreading outwards to find minimum distances.
Intuition
Treat all zero cells as sources and perform BFS to update distances of neighboring cells layer by layer.
Algorithm
- Initialize a queue and enqueue all cells with 0, setting their distance to 0.
- Set distance for other cells to infinity initially.
- While queue is not empty, dequeue a cell and check its neighbors.
- If neighbor distance can be minimized, update it and enqueue the neighbor.
💡 The BFS ensures shortest distances because it explores neighbors in increasing order of distance.
from typing import List
from collections import deque
class Solution:
def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:
m, n = len(mat), len(mat[0])
dist = [[float('inf')] * n for _ in range(m)]
q = deque()
for i in range(m):
for j in range(n):
if mat[i][j] == 0:
dist[i][j] = 0
q.append((i, j))
directions = [(1,0), (-1,0), (0,1), (0,-1)]
while q:
x, y = q.popleft()
for dx, dy in directions:
nx, ny = x + dx, y + dy
if 0 <= nx < m and 0 <= ny < n:
if dist[nx][ny] > dist[x][y] + 1:
dist[nx][ny] = dist[x][y] + 1
q.append((nx, ny))
return dist
# Driver code
if __name__ == '__main__':
sol = Solution()
mat = [[0,0,0],[0,1,0],[1,1,1]]
print(sol.updateMatrix(mat))
Line Notes
dist = [[float('inf')] * n for _ in range(m)]Initialize distances to infinity for all cells
if mat[i][j] == 0:Enqueue all zero cells as BFS starting points
directions = [(1,0), (-1,0), (0,1), (0,-1)]Define four possible neighbor directions
if dist[nx][ny] > dist[x][y] + 1:Update neighbor distance only if a shorter path is found
import java.util.*;
public class Solution {
public int[][] updateMatrix(int[][] mat) {
int m = mat.length, n = mat[0].length;
int[][] dist = new int[m][n];
for (int[] row : dist) Arrays.fill(row, Integer.MAX_VALUE);
Queue<int[]> q = new LinkedList<>();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (mat[i][j] == 0) {
dist[i][j] = 0;
q.offer(new int[]{i, j});
}
}
}
int[][] directions = {{1,0},{-1,0},{0,1},{0,-1}};
while (!q.isEmpty()) {
int[] cell = q.poll();
int x = cell[0], y = cell[1];
for (int[] d : directions) {
int nx = x + d[0], ny = y + d[1];
if (nx >= 0 && nx < m && ny >= 0 && ny < n) {
if (dist[nx][ny] > dist[x][y] + 1) {
dist[nx][ny] = dist[x][y] + 1;
q.offer(new int[]{nx, ny});
}
}
}
}
return dist;
}
public static void main(String[] args) {
Solution sol = new Solution();
int[][] mat = {{0,0,0},{0,1,0},{1,1,1}};
int[][] res = sol.updateMatrix(mat);
System.out.println(Arrays.deepToString(res));
}
}
Line Notes
int[][] dist = new int[m][n];Create distance matrix
Arrays.fill(row, Integer.MAX_VALUE);Initialize distances to max value
q.offer(new int[]{i, j});Add zero cells to BFS queue
if (dist[nx][ny] > dist[x][y] + 1)Relax neighbor distance if shorter path found
#include <iostream>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {
int m = mat.size(), n = mat[0].size();
vector<vector<int>> dist(m, vector<int>(n, INT_MAX));
queue<pair<int,int>> q;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (mat[i][j] == 0) {
dist[i][j] = 0;
q.push({i, j});
}
}
}
vector<pair<int,int>> directions = {{1,0},{-1,0},{0,1},{0,-1}};
while (!q.empty()) {
auto [x, y] = q.front(); q.pop();
for (auto& d : directions) {
int nx = x + d.first, ny = y + d.second;
if (nx >= 0 && nx < m && ny >= 0 && ny < n) {
if (dist[nx][ny] > dist[x][y] + 1) {
dist[nx][ny] = dist[x][y] + 1;
q.push({nx, ny});
}
}
}
}
return dist;
}
};
int main() {
Solution sol;
vector<vector<int>> mat = {{0,0,0},{0,1,0},{1,1,1}};
vector<vector<int>> res = sol.updateMatrix(mat);
for (auto &row : res) {
for (auto &val : row) cout << val << ' ';
cout << '\n';
}
return 0;
}
Line Notes
vector<vector<int>> dist(m, vector<int>(n, INT_MAX));Initialize distance matrix with max int
if (mat[i][j] == 0)Set distance zero for zero cells and enqueue
queue<pair<int,int>> q;Queue to perform BFS
if (dist[nx][ny] > dist[x][y] + 1)Update neighbor distance if shorter path found
var updateMatrix = function(mat) {
const m = mat.length, n = mat[0].length;
const dist = Array.from({length: m}, () => Array(n).fill(Infinity));
const q = [];
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (mat[i][j] === 0) {
dist[i][j] = 0;
q.push([i, j]);
}
}
}
const directions = [[1,0],[-1,0],[0,1],[0,-1]];
while (q.length) {
const [x, y] = q.shift();
for (const [dx, dy] of directions) {
const nx = x + dx, ny = y + dy;
if (nx >= 0 && nx < m && ny >= 0 && ny < n) {
if (dist[nx][ny] > dist[x][y] + 1) {
dist[nx][ny] = dist[x][y] + 1;
q.push([nx, ny]);
}
}
}
}
return dist;
};
// Test
console.log(updateMatrix([[0,0,0],[0,1,0],[1,1,1]]));
Line Notes
const dist = Array.from({length: m}, () => Array(n).fill(Infinity));Initialize distance matrix with Infinity
if (mat[i][j] === 0)Set zero cells distance to zero and enqueue
const q = [];Queue for BFS traversal
if (dist[nx][ny] > dist[x][y] + 1)Relax neighbor distance if shorter path found
TimeO(m * n)
SpaceO(m * n)
Each cell is enqueued and processed at most once, so BFS runs in linear time relative to matrix size.
💡 For a 100x100 matrix, this means about 10,000 operations, which is efficient for interviews.
Interview Verdict: Accepted
This is the optimal and accepted approach for this problem in interviews.