力扣刷题日记-296. 最佳的碰头地点

237 阅读2分钟
  • 思路:
  • 1.要求最小,那么人越多走的步数总和肯定是越大的
  • 2.所以应该找人少的那一行开始出发(题中人是用1表示)
  • 3.先计算出每一行分别有多少个1,计算出每一列分别有多少个1
  • 4.先进行首尾两行1个数的比较,哪一行少就往中间缩进,最终会缩成一行
  • 5.然后左右两列1个数的比较,哪一列少就往中间缩进,最终会缩到一个点上
  • 6.这个点就是最近的距离和的点, 在每一步缩进的时候累计步数,既可以得到最短距离和啦
  • 7.总结,先是上下压缩,再是左右压缩,最终压缩到一个点.这个点就是最佳点

给你一个 m x n  的二进制网格 grid ,其中 1 表示某个朋友的家所处的位置。返回 最小的 总行走距离 。

总行走距离 是朋友们家到碰头地点的距离之和。

我们将使用 曼哈顿距离 来计算,其中 distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y| 。

来源:力扣(LeetCode) 链接:leetcode.cn/problems/be… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


class Solution {
    public int minTotalDistance(int[][] grid) {
        int N = grid.length; // 行
        int M = grid[0].length; // 列
        int[] iOnes = new int[N]; // 统计每一行有多少个1
        int[] jOnes = new int[M]; // 统计每一列有多少个1
        for(int i = 0; i < N;i++) {
            for(int j = 0; j< M; j++) {
                if(grid[i][j] == 1) {
                    iOnes[i]++;
                    jOnes[j]++;
                }
            }
        }
        //统计工作完毕
//----------------------------------------
        //首行和尾行比较,谁小谁往中间累加缩进
        int total = 0;
        int up = 0; // 首行
        int down = N - 1; // 尾行
        int upRest = 0; // 上往下缩之前行的1个数总和
        int downRest = 0; // 下往上缩之前行的1个数总和
        while(up < down) {
            if(iOnes[up] + upRest <= iOnes[down] + downRest) {
                total += iOnes[up] + upRest;
                upRest += iOnes[up++];
            }else {
                total += iOnes[down] + downRest;
                downRest += iOnes[down--];
            }
        }
//----------------------------------------
        //首列和尾列比较,谁小谁往中间累加缩进
        int left = 0; // 首列
        int right = M - 1; // 尾列
        int leftRest = 0; // 左往右缩进之前的1个数总和
        int rightRest = 0; // 右往左锁进之前的1个数总和
        while(left < right) {
            if(jOnes[left] + leftRest <= jOnes[right] + rightRest) {
                total += jOnes[left] + leftRest;
                leftRest += jOnes[left++];
            }else {
                total += jOnes[right] + rightRest;
                rightRest += jOnes[right--];
            }
        }
//-------------------结果
        return total;

    }
}