01矩阵

问题描述

给定矩阵,求出每个元素离最近的 0 的距离,注意最近的 0 可以不和该元素同一行

输入案例

0 0 0
0 1 0
1 1 1

输出

0 0 0
0 1 0
1 2 1

解决思路

  咋一看貌似可以用DP来做哎,如果知道了一个元素的附近邻居的最小距离,然后取邻居的最小距离+1不就出来了嘛。大体思路确实如此,但是怎样获得邻居元素的结果呢?

具体思路

  我们在遍历的时候总是根据从左到右、从上到下的顺序来的,对于某个我们想要考虑的元素,如果他的左边邻居和上面的邻居都已经被计算过,那么我们就可以根据他的左、上边邻居得到他的计算结果值。第一次遍历结束后,还只是考虑了从左上邻居的情况,没有考虑右下邻居的情况,然后再进行一次遍历,从右往左、从下往上遍历,此时就可以根据右、下邻居计算出一个值,这个值要和第一遍根据左上邻居计算出来的结果进行比较取小。即得到该位置处的计算结果。

  可能有同学会问了,为什么不能用一次遍历呢,直接把该元素的上下左右四个邻居全部考虑进来呢?对于这个问题,我肯定是摔过跟头的啊!我们可以考虑这样一点,从上到下,从左到右遍历的时候,对于给定位置的元素,他的左上邻居才有计算结果,右下邻居根本还没得到计算,怎么可以把非计算结果代带进去比较呢?举个例子,比如矩阵中的某个小区域是这个样子:

1 0 1 1
1 1 1 1
0 0 1 1
1 0 1 1

只遍历一次的前两行结果为:
1 0 1 2
1 1 2 2

  对于第2行最后一个结果,明显错了对不对,因为他直接把他的下邻居的 1 拿来计算了。

Java 实现

 1 class Solution {
 2     private static int[] dx = {-1, 0, 1, 0}; //  上 左 下 右
 3     private static int[] dy = {0, -1, 0, 1};
 4     
 5     public static int[][] updateMatrix(int[][] matrix) {
 6         int m = matrix.length, n = matrix[0].length;
 7         for (int i = 0; i < m; i++) {
 8             for (int j = 0; j < n; j++) {
 9                 if (matrix[i][j] == 0) continue;
10                 int newI, newJ, min=10001;
11                 // 左、上邻居
12                 for (int k = 0; k < 2; k++) {
13                     newI = i + dx[k];
14                     newJ = j + dy[k];
15                     if (0 <= newI && newI < m && 0 <= newJ && newJ < n) {
16                         min = Math.min(min, matrix[newI][newJ]);
17                     }
18                 }
19                 matrix[i][j] = min + 1;
20             }
21         }
22         for (int i = m-1; i >=0; i--) {
23             for (int j = n-1; j >=0; j--) {
24                 if (matrix[i][j] == 0) continue;
25                 int newI, newJ, min=10001;
26                 // 右 下邻居
27                 for (int k = 2; k < 4; k++) {
28                     newI = i + dx[k];
29                     newJ = j + dy[k];
30                     if (0 <= newI && newI < m && 0 <= newJ && newJ < n) {
31                         min = Math.min(min, matrix[newI][newJ]);
32                     }
33                 }
34                 matrix[i][j] = Math.min(matrix[i][j], min + 1);
35             }
36         }
37         return matrix;
38     }
39 }        
原文地址:https://www.cnblogs.com/dogeLife/p/11378456.html