20. Shortest Distance from All Buildings

Link to the problem

Description

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.

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

Example

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.

Idea

From each building, do a level order traversal of the graph. Increment each cell with the distance to that building, and increment the count. Only consider empty slots that are reachable by all buildings.

Solution

class Solution {
public:
    int shortestDistance(vector<vector<int> > &grid) {
        int n_row = grid.size();
        if (!n_row) return -1;
        int n_col = grid[0].size();
        if (!n_col) return -1;
        vector<vector<int> > count(n_row, vector<int>(n_col, 0));
        vector<vector<int> > dist(n_row, vector<int>(n_col, 0));
        vector<pair<int, int> > didj = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        int n_house = 0;
        for (int i = 0; i < n_row; i++) {
            for (int j = 0; j < n_col; j++) {
                if (grid[i][j] != 1) continue;
                ++n_house;
                vector<pair<int, int> > level = {{i, j}};
                vector<vector<bool> > visited(n_row, vector<bool>(n_col, false));
                visited[i][j] = true;
                int n_level = 0;
                while (!level.empty()) {
                    ++n_level;
                    vector<pair<int, int> > new_level;
                    for (auto it = level.begin(); it != level.end(); ++it) {
                        int row = it->first, col = it->second;
                        for (auto diff = didj.begin(); diff != didj.end(); ++diff) {
                            int new_row = row + diff->first, new_col = col + diff->second;
                            if (0 <= new_row && new_row < n_row &&
                               0 <= new_col && new_col < n_col &&
                               !visited[new_row][new_col] && grid[new_row][new_col] == 0) {
                                visited[new_row][new_col] = true;
                                dist[new_row][new_col] += n_level;
                                ++count[new_row][new_col];
                                new_level.push_back(pair<int, int> {new_row, new_col});
                            }
                        }
                    }
                    level = new_level;
                }
            }
        }
        int rtn = INT_MAX;
        for (int i = 0; i < n_row; ++i) {
            for (int j = 0; j < n_col; ++j) {
                if (grid[i][j] == 0 && count[i][j] == n_house) {
                    rtn = min(rtn, dist[i][j]);
                }
            }
        }
        return (rtn == INT_MAX) ? -1 : rtn;
    }
};

72 / 72 test cases passed.
Runtime: 82 ms

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Lesson 1 A private conversation 私人谈话Last week I went to t...
    造物家英语阅读 140,080评论 2 57
  • 人烟稀少鸟飞寂,仙雾缭绕缘何起?书生急往河边去,察探究竟看仔细。昔日牛郎遇织女,成就佳话好传奇。莫非今日好运气,碰...
    芃悠阅读 227评论 2 6
  • 小米最近日子并不好过 依据IDC的统计数据,2016年榜首季度,我国智能手机出货量冠军现已不再是小米。小米已被华为...
    FWLSJ联盟阅读 293评论 0 1
  • 世间安有两全法,不负如来不负卿!从古至今爱情的话题经久不衰!但往往都是既负如来又负卿!初涉爱河以为爱情就是付...
    绿萝悠悠阅读 256评论 1 1
  • 我常常喜欢给别人提些建议,或是鸡汤,好像每个人都会因为给出的那些建议过得开心无比一路顺畅。 经验这种东西,并不一定...
    槿木123阅读 549评论 0 0