Build Post Office

Given a 2D grid, each cell is either an house 1 or empty 0 (the number zero, one), find the place to build a post office, the distance that post office to all the house sum is smallest. Return the smallest distance. Return -1 if it is not possible.

Notice
  • You can pass through house and empty.
  • You only build post office on an empty.

Example

Given a grid:

0 1 0 0
1 0 1 1
0 1 0 0

return6. (Placing a post office at (1,1), the distance that post office to all the house sum is smallest.)

S1: 存下所有有房子的点,再遍历空点求最小距离 O(mnk) k为房子数

    int shortestDistance(vector<vector<int>>& grid) {
        int m = grid.size();
        if (m == 0) {
            return -1;
        }
        int n = grid[0].size();
        list<int> houseX;
        list<int> houseY;
        int result = INT_MAX;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 1) {
                    houseX.push_back(i);
                    houseY.push_back(j);
                }
            }
        }
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 0) {
                    int dist = 0;
                    for (int k : houseX) {
                        dist += abs(k - i);
                    }
                    for (int k : houseY) {
                        dist += abs(k - j);
                    }
                    if (dist < result) {
                        result = dist;
                    }
                }
            }
        }
        if (result == INT_MAX) {
            return -1;
        } else {
            return result;
        }

    }

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

S: 逆向思维BFS O(mnk) k是房子数目

以每个房子为起始进行BFS记录房子到每个空地的距离,累加。

用count数组记录每块空地被bfs访问的次数,若count小于房子数目则有房子不可到达,排除。

class Solution {
public:
    int shortestDistance(vector<vector<int>>& grid) {
        int m = grid.size();
        if (m == 0) {
            return -1;
        }
        int n = grid[0].size();
        int houseCount = 0;
        vector<vector<int>> dist(m, vector<int>(n, 0));
        vector<vector<int>> count(m, vector<int>(n, 0));
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 1) {
                    houseCount++;
                    bfs(grid, i, j, dist, count);
                }
            }
        }
        int result = INT_MAX;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 0 && houseCount == count[i][j]) {
                    result = min(result, dist[i][j]);
                }
            }
        }
        return result == INT_MAX? -1: result;
    }
private:
    void bfs(vector<vector<int>>& grid, int x, int y, vector<vector<int>>& dist,
             vector<vector<int>>& count) {
        queue<Node> q;
        int curDist = 0;
        vector<vector<bool>> visited(grid.size(), vector<bool>(grid[0].size(), false));
        q.push(Node(x, y, curDist));
        while (!q.empty()) {
            Node node = q.front();
            q.pop();
            dist[node.x][node.y] += node.dist;
            count[node.x][node.y]++;
            vector<int> dx{1, 0, -1, 0};
            vector<int> dy{0, 1, 0, -1};
            for (int i = 0; i < 4; ++i) {
                int x1 = node.x + dx[i];
                int y1 = node.y + dy[i];
                if (x1 < grid.size() && x1 >= 0 && y1 < grid[0].size() && y1 >= 0 && grid[x1][y1] == 0 && !visited[x1][y1] && grid[x1][y1] != -1) {
                    visited[x1][y1] = true;
                    q.push(Node(x1, y1, node.dist + 1));
                }
            }
        }
    }
    struct Node {
        int x;
        int y;
        int dist;
        Node(int a, int b, int d): x(a), y(b), dist(d) {}
    };
};

results matching ""

    No results matching ""