[Leetcode] 317. Shortest Distance from All Buildings 解题报告

来源:互联网 发布:短信变号软件 编辑:程序博客网 时间:2024/06/09 17:27

题目

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 01 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.

思路

一道典型的BFS题目,其基本思路是:对于每一个building,我们在grid上利用BFS来获取所有空白处到该建筑的距离;当所有building的结果都计算出来之后,对应位置加起来,最小值即为最优选择。朴素的代码可能需要另外开辟存储空间以及访问标记。

在下面的实现中,我们巧妙利用了grid中空白处的值0。也就是说,在对第一个建筑物求BFS的时候,我们只遍历grid[x][y] == 0的地方,一旦遍历之后,就将其值置为-1;在对第二个建筑物求BFS的时候,我们只遍历grid[x][y] == -1的地方,并且在遍历之后,就将其值置为-2,以此类推,直到所有的建筑物都被遍历。

代码

class Solution {public:    int shortestDistance(vector<vector<int>>& grid) {        if(grid.size() == 0) {            return 0;        }        int row_num = grid.size(), col_num = grid[0].size();        int ret = 0, flag = 0;        vector<pair<int, int>> dir{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};        vector<vector<int>> count(row_num, vector<int>(col_num, 0));        for(int i = 0; i < row_num; ++i) {            for(int j = 0; j < col_num; ++j) {                if(grid[i][j] != 1) {                    continue;                }                ret = INT_MAX;  // It is a bit tricky to understand why here we define ret and intiailize it as INT_MAX                                // Each time it is first initialized as INT_MAX, and then updated as minimal summed distances                queue<pair<int, int>> que;                que.push(make_pair(i * col_num + j, 0));    // map 2D matrix to 1D array                while(!que.empty()) {                    auto val = que.front();                    que.pop();                    for(auto v : dir) {                        int x = val.first / col_num + v.first;                        int y = val.first % col_num + v.second;                        if(x < 0 || x >= row_num || y < 0 || y >= col_num || grid[x][y] != flag) {                            continue;                        }                        count[x][y] += val.second + 1;                        --grid[x][y];                        ret = min(ret, count[x][y]);                        que.push(make_pair(x * col_num + y, val.second + 1));                    }                }                --flag;            }        }        return ret == INT_MAX ? -1 : ret;    }};

阅读全文
0 0
原创粉丝点击