[LeetCode317]Shortest Distance from All Buildings

You want to build a house on an empty land which reaches all buildings in the shortest amount of distance. You are given a 2D grid of values 0, 1 or 2, where:

Each 0 marks an empty land which you can pass by freely.
Each 1 marks a building which you cannot pass through.
Each 2 marks an obstacle which you cannot pass through.
The distance is calculated using Manhattan Distance, where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|.

For example, given three buildings at (0,0), (0,4), (2,2), and an obstacle at (0,2):

    1 - 0 - 2 - 0 - 1
    |   |   |   |   |
    0 - 0 - 0 - 0 - 0
    |   |   |   |   |
    0 - 0 - 1 - 0 - 0
The point (1,2) is an ideal empty land to build a house, as the total travel distance of 3+3+1=7 is minimal. So return 7.

Note:
There will be at least one building. If it is not possible to build such house according to the above rules, return -1.

Hide Company Tags Google Zenefits
Hide Tags Breadth-first Search
Hide Similar Problems (M) Walls and Gates (H) Best Meeting Point

Discuss:

https://leetcode.com/discuss/questions/oj/shortest-distance-from-all-buildings

這道題一看就知道要用BFS。但有很多細節的地方:比如,最後找出的point必須是所有building都可以到達的,所以如果是:

{1,1}
{0,1}

這種情況就應該return -1;

我們traverse整個grid, 一旦發現1 就開始BFS. 對於第一個building(which is grid[i][j] == 1) 它可以到達的地方是所有爲0 的點,一旦它visited過這些點,我們update其爲-1。 對於第二個building,我們只能走那些-1的點,爲什麼呢?因爲如果第一個點不能到達某一個點p, 那麼這個p已經不滿足題目要求:You want to build a house on an empty land which reaches *all* buildings in the shortest amount of distance. 我們沒必要去check這個點。。因此最終我們traverse total 這個matrix的時候不僅要跳過那些 total[i][j] == 0 的點(因爲這些點是building或者obstacle的位置), 而且我們還要跳過 total[i][j] != canAchieve 的點(因爲這些點不能被所有的building到達,其實 canAchieve 這個變量記錄了一共有多少building)。。

理清這些思路就可以寫出下面的code,40ms:

class Solution {
public:
    int shortestDistance(vector<vector<int>>& grid) {
        if(grid.empty()) return -1;
        int m = grid.size(), n = grid[0].size();
        vector<vector<int>> total(m,vector<int>(n,0));// using vector to store information about the total distance for each possible node.
        vector<vector<int>> newGrid = grid;// we dont want to change original matrix;
        int canAchieve = 0, minDist = INT_MAX;
        vector<pair<int, int>> dirs = {{0,1}, {1,0}, {0,-1}, {-1,0}};
        for(int i = 0; i<m; ++i){
            for(int j = 0; j<n; ++j){
                if(grid[i][j] == 1){
                    queue<pair<int, int>> q;
                    q.push(make_pair(i,j));// current 1 position, we start BFS;
                    vector<vector<int>> dist(m,vector<int>(n,0));
                    //using dist to store distance information start from current building.
                    while(!q.empty()){
                        auto cur = q.front();
                        q.pop();
                        for(auto d : dirs){
                            int newX = cur.first+d.first, newY = cur.second+d.second;
                            if(newX<m && newX>=0 && newY<n && newY >=0 && newGrid[newX][newY] == canAchieve){
                                --newGrid[newX][newY];
                                dist[newX][newY] = dist[cur.first][cur.second]+1;
                                total[newX][newY] += dist[newX][newY];
                                q.push(make_pair(newX, newY));
                            }
                        }
                    }
                    --canAchieve;//after each update, we change the node we can achieve by --canAchieve.
                }
            }
        }
        for(int i = 0; i<total.size(); ++i){
            for (int j = 0; j<total[0].size(); ++j) {
                if(total[i][j] && newGrid[i][j] == canAchieve) minDist = min(minDist, total[i][j]);// insure all building can achieve this point!;
            }
        }
        return minDist == INT_MAX ? -1 : minDist;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章