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.

题目来自leetcode,好难...

分析:

这道题目需要准备3个container

vector<vector<int> > values
用来存放每个空格起步的情况下,到达所有房子需要多少步

vector<vector<int> > nums
某个特定的格子可以走到多少个房子,如果走不到所有房子,当然不考虑

vector<pair<int, int> > buindlings
来存储房子们的位置,

具体的过程是这样的,假设开始的时候我们的矩阵是这样:

1 - 0 - 2 - 0 - 1
|   |   |   |   |
0 - 0 - 0 - 0 - 0
|   |   |   |   |
0 - 0 - 1 - 0 - 0

而这时候的value矩阵应该是这样的:

0 - ? - X - ? - 0
|   |   |   |   |
? - ? - ? - ? - ?
|   |   |   |   |
? - ? - 0 - ? - ?

当你bfs过左上角的房子之后,你的矩阵会变成这样

0 - 1 - X - 1 - 0
|   |   |   |   |
1 - 2 - 3 - 2 - 1
|   |   |   |   |
2 - 3 - 0 - 3 - 2

当你bfs过右上角的房子之后,你的矩阵会变成这样

0 - 6 - X - 6 - 0
|   |   |   |   |
6 - 6 - 6 - 6 - 6
|   |   |   |   |
0 - 0 - 1 - 0 - 0

当你bfs过最后一个房子之后,你得到的矩阵是这样

0 - 9 - X - 9 - 0
|   |   |   |   |
9 - 8 - 7 - 8 - 9
|   |   |   |   |
10- 9 - 0 - 9 - 10

这个矩阵的每个元素记录着如果从当前坐标出发,走到所有房子需要的步数总和,最后找到最小值就可以了。

解法:

class Solution {
public:
    bool bfs(int first, 
                int second, 
                int m, 
                int n, 
                vector<pair<int, int> > &buildings, 
                vector<vector<int> > &values, 
                vector<vector<int> > &nums, 
                vector<vector<int> > &grid) {
        queue<pair<int, int> > Q;
        vector<vector<bool> > visited(m, vector<bool>(n, false) );
        Q.push(make_pair(first, second) );
        int depth = 0;
        while (!Q.empty() ) {
            int size = Q.size();
            for (int s = 0; s < size; s++) {
                pair<int, int> temp = Q.front();
                Q.pop();
                int i = temp.first;
                int j = temp.second;
                if (values[i][j] == INT_MAX) {
                    values[i][j] = depth;
                } else {
                    values[i][j] += depth;
                }
                nums[i][j] += 1;

                if (i - 1 >= 0 && visited[i - 1][j] == false) {
                    visited[i - 1][j] = true;
                    if (grid[i - 1][j] == 0) {
                        Q.push(make_pair(i - 1, j) );
                    }
                }
                if (i + 1 < m && visited[i + 1][j] == false) {
                    visited[i + 1][j] = true;
                    if (grid[i + 1][j] == 0) {
                        Q.push(make_pair(i + 1, j) );
                    }
                }
                if (j - 1 >= 0 && visited[i][j - 1] == false) {
                    visited[i][j - 1] = true;
                    if (grid[i][j - 1] == 0) {
                        Q.push(make_pair(i, j - 1) );
                    }
                }
                if (j + 1 < n && visited[i][j + 1] == false) {
                    visited[i][j + 1] = true;
                    if (grid[i][j + 1] == 0) {
                        Q.push(make_pair(i, j + 1) );
                    }
                }
            }
            depth++;
        }
        for (int i = 0; i < buildings.size(); i++) {
            if (visited[buildings[i].first][buildings[i].second] == false) {
                return false;
            }
        }
        return true;
    }

    int shortestDistance(vector<vector<int>>& grid) {
        if (grid.size() == 0 || grid[0].size() == 0) {
            return -1;
        }
        int m = grid.size();
        int n = grid[0].size();
        vector<pair<int, int> > buildings;
        vector<vector<int> > values(m, vector<int>(n, INT_MAX) );
        vector<vector<int> > nums(m, vector<int>(n, 0) );
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) {
                    buildings.push_back(make_pair(i, j) );
                }
            }
        }
        for (int i = 0; i < buildings.size(); i++) {
            int first = buildings[i].first;
            int second = buildings[i].second;
            if (!bfs(first, second, m, n, buildings, values, nums, grid) ) {
                return -1;
            }
        }
        int minDis = INT_MAX;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 0 && nums[i][j] == buildings.size() ) {
                    minDis = values[i][j] > minDis ? minDis : values[i][j];
                }
            }
        }
        return (minDis == INT_MAX) ? -1 : minDis;
    }
};

results matching ""

    No results matching ""