LeetCode 296. Best Meeting Point(最佳见面点)

原题网址:https://leetcode.com/problems/best-meeting-point/

A group of two or more people wants to meet and minimize the total travel distance. You are given a 2D grid of values 0 or 1, where each 1 marks the home of someone in the group. The distance is calculated using Manhattan Distance, where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|.

For example, given three people living at (0,0)(0,4), and (2,2):

1 - 0 - 0 - 0 - 1
|   |   |   |   |
0 - 0 - 0 - 0 - 0
|   |   |   |   |
0 - 0 - 1 - 0 - 0

The point (0,2) is an ideal meeting point, as the total travel distance of 2+2+2=6 is minimal. So return 6.

Hint:

  1. Try to solve it in one dimension first. How can this solution apply to the two dimension case?

曼哈顿距离有个特点:水平距离与垂直距离独立,因此分别计算水平的最佳点和垂直的最佳点,组合起来就是最佳的见面地点。

一维上的最佳地点,是坐标的中位数,这里有一个非常好的寻找中位数的算法,两面夹逼。

public class Solution {
    private int median(int[] nums) {
        int i=0, j=nums.length-1;
        while (true) {
            while (ii; a--) {
            right+=nums[a];
            dist+=right;
        }
        return dist;
    }
    public int minTotalDistance(int[][] grid) {
        int[] v = new int[grid.length];
        int[] h = new int[grid[0].length];
        for(int i=0; i

进一步优化:

public class Solution {
    public int minTotalDistance(int[][] grid) {
        int[] cols = new int[grid[0].length];
        int[] rows = new int[grid.length];
        for(int i=0; i

进一步优化:

public class Solution {
    public int minTotalDistance(int[][] grid) {
        if (grid == null || grid.length == 0 || grid[0].length == 0) return 0;
        int[] h = new int[grid[0].length];
        int[] v = new int[grid.length];
        for(int i = 0; i < grid.length; i++) {
            for(int j = 0; j < grid[i].length; j++) {
                h[j] += grid[i][j];
                v[i] += grid[i][j];
            }
        }
        return distance(h) + distance(v);
    }
    private int distance(int[] nums) {
        if (nums.length <= 1) return 0;
        int dist = 0;
        int i = 0, j = nums.length - 1;
        int di = nums[i], dj = nums[j];
        while (i < j) {
            if (di <= dj) {
                dist += di;
                di += nums[++i];
            } else {
                dist += dj;
                dj += nums[--j];
            }
        }
        return dist;
    }
}


你可能感兴趣的:(距离,曼哈顿距离,最短距离,中位数,夹逼,累积,双向扫描)