[Locked] Shortest Distance from All Buildings
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 can only move up, down, left and right. 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.
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.
分析:
这题如果不考虑obstacle的存在的话,与另一道leetcode题目一样,分成x轴和y轴,根据值为1的点的坐标,直接算出最小距离;然而多了一个obstacle,这题又更像是gates and walls这题了,不同的是,对于每个为0的点,各个建筑物到它的最近的距离都要计算出来并累加,而不是算最近距离的最小值。K为building个数,M、N分别为长和宽,时间复杂度为O(KMN),空间复杂度为O(MN)
代码:
//计算每个岛到坐标为(i, j)的building的最短距离 void dfs(int i, int j, int cur, vector<vector<int> > &dist, vector<vector<int> > &grids) { if(cur > dist[i][j]) return; dist[i][j] = cur++; if(grids[i][j + 1] == 0) dfs(i, j + 1, cur, dist, grids); if(grids[i][j - 1] == 0) dfs(i, j - 1, cur, dist, grids); if(grids[i + 1][j] == 0) dfs(i + 1, j, cur, dist, grids); if(grids[i - 1][j] == 0) dfs(i - 1, j, cur, dist, grids); return; } //迭代计算总距离矩阵,并重置距离矩阵 void postProcess(vector<vector<int> > &dist, vector<vector<int> > &totaldist, vector<vector<int> > &grids) { for(int i = 0; i < grids.size(); i++) for(int j = 0; j < grids[0].size(); j++) { if(grids[i][j] == 0) totaldist[i][j] += dist[i][j]; dist[i][j] = INT_MAX; } return; } //主要功能函数 int shortestDist(vector<vector<int> > &grids) { //设立岗哨 grids.insert(grids.begin(), vector<int> (grids[0].size(), 2)); grids.push_back(vector<int> (grids[0].size(), 2)); for(auto &v : grids) { v.insert(v.begin(), 2); v.push_back(2); } //声明并初始化距离矩阵 vector<vector<int> > dist(grids); for(auto &v : dist) for(int &i : v) i = INT_MAX; //声明并初始化总距离矩阵 vector<vector<int> > totaldist(grids.size(), vector<int> (grids[0].size(), 0)); //对每个building进行扩展,计算其到周边岛屿的最小距离 for(int i = 0; i < grids.size(); i++) { for(int j = 0; j < grids[0].size(); j++) { if(grids[i][j] == 1) { dfs(i, j, 0, dist, grids); postProcess(dist, totaldist, grids); } } } //在总距离矩阵中找到最小距离 int sd = INT_MAX; for(int i = 0; i < grids.size(); i++) for(int j = 0; j < grids[0].size(); j++) if(grids[i][j] == 0) sd = min(sd, totaldist[i][j]); //去除岗哨,还原输入矩阵 grids.pop_back(); grids.erase(grids.begin()); for(auto &v : grids) { v.pop_back(); v.erase(v.begin()); } return sd; }