542. 01 Matrix
Given a matrix consists of 0 and 1, find the distance of 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.
- DFS failed with TLE; I was insane to try dfs first …; think it twice next time.
This bfs is a competition of all zeros, zeros capture closest ones in turn.
public int[][] updateMatrix(int[][] matrix) {
int[][] result = new int[matrix.length][matrix[0].length];
for(int i = 0; i < result.length; i++)
for(int j = 0; j < result[0].length; j++)
if(matrix[i][j] == 1)
result[i][j] = Integer.MAX_VALUE;
int[] xs = {0,0,-1,1}, ys = {1,-1,0,0};
Queue<int[]> q = new LinkedList<>();
for(int i = 0; i < result.length; i++)
for(int j = 0; j< result[0].length; j++)
if(matrix[i][j] == 0) // start from all zeros, then step 1, step 2...
q.offer(new int[]{i,j});
while(!q.isEmpty()) {
int[] curr = q.poll();
for(int k = 0; k < 4; k++) {
int x = curr[0] + xs[k], y = curr[1] + ys[k];
if(x < 0 || y < 0 || x >= result.length || y >= result[0].length) continue;
if(result[x][y] > result[curr[0]][curr[1]]+1) {
result[x][y] = result[curr[0]][curr[1]]+1;
q.offer(new int[] {x,y});
}
}
}
return result;
}
- Two pass dp
public int[][] updateMatrix(int[][] matrix) {
int MAX = matrix.length + matrix[0].length;
int[][] dp = new int[matrix.length][matrix[0].length];
for(int i = 0; i < dp.length; i++) {
for(int j = 0; j < dp[0].length; j++) {
if(matrix[i][j] == 1){
int top = i-1 >= 0 ? dp[i-1][j] : MAX;
int left = j-1 >= 0 ? dp[i][j-1] : MAX;
dp[i][j] = Math.min(left, top)+1;
}
}
}
for(int i = dp.length-1; i >= 0; i--) {
for(int j = dp[0].length-1; j >= 0; j--) {
if(matrix[i][j] == 1) {
int right = j+1 < dp[0].length ? dp[i][j+1] : MAX;
int bottom = i+1 < dp.length ? dp[i+1][j] : MAX;
dp[i][j] = Math.min(dp[i][j], Math.min(right, bottom)+1);
}
}
}
return dp;
}