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

Posted jmspan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 (i<j && nums[i]==0) i++;
            while (i<j && nums[j]==0) j--;
            if (i==j) break;
            int min = Math.min(nums[i], nums[j]);
            nums[i] -= min;
            nums[j] -= min;
        
        return i;
    
    private int distance(int[] nums, int i) 
        int dist=0;
        for(int a=0, left=0; a<i; a++) 
            left+=nums[a];
            dist+=left;
        
        for(int a=nums.length-1, right=0; a>i; 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<grid.length; i++) 
            for(int j=0; j<grid[i].length; j++) 
                if (grid[i][j]==1) 
                    v[i]++;
                    h[j]++;
                
            
        
        return distance(h, median(h.clone())) + distance(v, median(v.clone()));
    

进一步优化:

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<grid.length; i++) 
            for(int j=0; j<grid[i].length; j++) 
                if (grid[i][j]==1) 
                    cols[j] ++;
                    rows[i] ++;
                
            
        
        return minDist(cols) + minDist(rows);
    
    private int minDist(int[] nums) 
        int dist = 0;
        int left = 0, right = 0;
        int i = 0, j = nums.length-1;
        while (i<=j) 
            if (left <= right) 
                dist += left;
                left += nums[i++];
             else 
                dist += right;
                right += nums[j--];
            
        
        if (left<=right) dist+=left; else dist+=right;
        return dist;
    

进一步优化:

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;
    


以上是关于LeetCode 296. Best Meeting Point(最佳见面点)的主要内容,如果未能解决你的问题,请参考以下文章

296. Best Meeting Point

296. Best Meeting Point

[LeetCode] Best Meeting Point 最佳开会地点

LeetCode Best Time to Buy and Sell Stock with Cooldown

[LeetCode]Best Time to Buy and Sell Stock II

LeetCode 121. Best Time to Buy and Sell Stock