问题:
难度:medium
说明:
输入给出一个矩阵,只包含 0 1 值,现在需要把矩阵每个位置距离 0 是最近的距离算出来,然后放到 结果集中。
题目连接:https://leetcode.com/problems/01-matrix/submissions/
输入范围:
- 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.
输入案例:
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]]
我的代码:
这道题用 dp 比较适合,但是 dp 是真的说是容易,用就难,所以我用一个数组装所有的 0 位置,然后从左上 往 右下遍历,因为左上都是 记录 最小的 0 距离,所以 拿到 左上和对着没有遍历的 0 的集合统计一次最短距离就可以了,因为 10000 数据以内,而且 0 1 都需要存在,所以效率过得去。
而且再复用原来的矩阵就行,不过还是没 dp 快。
所以是 min (left, up, right, down) 四个方向最小距离。
Java:
class Solution {
private static int cacheZero[][] = new int[10000][2];
public int[][] updateMatrix(int[][] matrix) {
if(matrix.length == 0 || matrix[0].length == 0) return matrix;
int x = matrix.length, y =matrix[0].length, zeroIndex = 0, zeroLast = -1;
for(int i = 0; i < x; i ++) {
for(int j = 0; j < y; j ++) {
if(matrix[i][j] == 0) {
cacheZero[++ zeroLast][0] = i;
cacheZero[zeroLast][1] = j;
}
}
}
for(int i = 0; i < x; i ++) {
for(int j = 0; j < y; j ++) {
if(matrix[i][j] == 0) {
++ zeroIndex;
matrix[i][j] = 0;
}
else {
int id = i - 1, jd = j - 1, ia = i + 1, ja = j + 1,
up = id >= 0 ? matrix[id][j] + 1 : Integer.MAX_VALUE,
left = jd >= 0 ? matrix[i][jd] + 1 : Integer.MAX_VALUE;
if(up == 1 || left == 1
|| (ia < x && matrix[ia][j] == 0)
|| (ja < y && matrix[i][ja] == 0)) matrix[i][j] = 1;
else {
int rightOrDown = getRD(zeroIndex, zeroLast, cacheZero, i, j);
matrix[i][j] = Math.min(up, Math.min(left, rightOrDown));
}
}
}
}
return matrix;
}
public int getRD(int zeroIndex, int zeroLast, int[][] cacheZero, int i, int j) {
int min = Integer.MAX_VALUE;
for(int ii = zeroIndex; ii <= zeroLast; ii ++) {
int dis = Math.abs(cacheZero[ii][0] - i) + Math.abs(cacheZero[ii][1] - j);
min = Math.min(dis, min);
}
return min;
}
}