[LeetCode] 296. 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|.

Example:

Input: 

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

Output: 6 

Explanation: Given three people living at (0,0), (0,4), and (2,2):
             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?

 

這道題讓我們求最佳的開會地點,該地點需要到每個為1的點的曼哈頓距離之和最小,題目中給了提示,讓從一維的情況來分析,先看一維時有兩個點A和B的情況,

______A_____P_______B_______

可以發現,只要開會為位置P在 [A, B] 區間內,不管在哪,距離之和都是A和B之間的距離,如果P不在 [A, B] 之間,那么距離之和就會大於A和B之間的距離,現在再加兩個點C和D:

______C_____A_____P_______B______D______

通過分析可以得出,P點的最佳位置就是在 [A, B] 區間內,這樣和四個點的距離之和為AB距離加上 CD 距離,在其他任意一點的距離都會大於這個距離,那么分析出來了上述規律,這題就變得很容易了,只要給位置排好序,然后用最后一個坐標減去第一個坐標,即 CD 距離,倒數第二個坐標減去第二個坐標,即 AB 距離,以此類推,直到最中間停止,那么一維的情況分析出來了,二維的情況就是兩個一維相加即可,參見代碼如下:

 

解法一:

class Solution {
public:
    int minTotalDistance(vector<vector<int>>& grid) {
        vector<int> rows, cols;
        for (int i = 0; i < grid.size(); ++i) {
            for (int j = 0; j < grid[i].size(); ++j) {
                if (grid[i][j] == 1) {
                    rows.push_back(i);
                    cols.push_back(j);
                }
            }
        }
        return minTotalDistance(rows) + minTotalDistance(cols);
    }
    int minTotalDistance(vector<int> v) {
        int res = 0;
        sort(v.begin(), v.end());
        int i = 0, j = v.size() - 1;
        while (i < j) res += v[j--] - v[i++];
        return res;
    }
};

 

我們也可以不用多寫一個函數,直接對 rows 和 cols 同時處理,稍稍能簡化些代碼:

 

解法二:

class Solution {
public:
    int minTotalDistance(vector<vector<int>>& grid) {
        vector<int> rows, cols;
        for (int i = 0; i < grid.size(); ++i) {
            for (int j = 0; j < grid[i].size(); ++j) {
                if (grid[i][j] == 1) {
                    rows.push_back(i);
                    cols.push_back(j);
                }
            }
        }
        sort(cols.begin(), cols.end());
        int res = 0, i = 0, j = rows.size() - 1;
        while (i < j) res += rows[j] - rows[i] + cols[j--] - cols[i++];
        return res;
    }
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/296

 

類似題目:

Minimum Moves to Equal Array Elements II

Shortest Distance from All Buildings

 

參考資料:

https://leetcode.com/problems/best-meeting-point/

https://leetcode.com/problems/best-meeting-point/discuss/74186/14ms-java-solution

https://leetcode.com/problems/best-meeting-point/discuss/74244/Simple-Java-code-without-sorting.

https://leetcode.com/problems/best-meeting-point/discuss/74193/Java-2msPython-40ms-two-pointers-solution-no-median-no-sort-with-explanation

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM