zoukankan      html  css  js  c++  java
  • 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 }        
  • 相关阅读:
    不用找了,比较全的signalR例子已经为你准备好了(2)---JqGrid 服务端刷新方式-注释详细-DEMO源码下载
    不用找了,比较全的signalR例子已经为你准备好了.
    26之前,26之后
    SSIS从理论到实战,再到应用(7)----常用的数据类型转换操作
    SSIS从理论到实战,再到应用(6)----SSIS的自带日志功能
    SSIS从理论到实战,再到应用(5)----流程控制之Foreach循环
    SSIS从理论到实战,再到应用(4)----流程控制之For循环
    SSIS从理论到实战,再到应用(3)----SSIS包的变量,约束,常用容器
    SSIS从理论到实战,再到应用(2)----SSIS包的控制流
    Android学习笔记(十二)BroadcastReceiver的有序广播和优先级
  • 原文地址:https://www.cnblogs.com/dogeLife/p/11378456.html
Copyright © 2011-2022 走看看