您的位置:首页 > 产品设计 > UI/UE

[LeetCode317]Shortest Distance from All Buildings

2015-12-17 03:59 543 查看
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;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode