Given a 2D grid, each cell is either a wall 2
, an house 1
or empty 0
(the number zero, one, two), find a place to build a post office so that the sum of the distance from the post office to all the houses is smallest.
Return the smallest sum of distance. Return -1
if it is not possible.
Example
Example 1:
Input:[[0,1,0,0,0],[1,0,0,2,1],[0,1,0,0,0]]
Output:8
Explanation: Placing a post office at (1,1), the distance that post office to all the house sum is smallest.
Example 2:
Input:[[0,1,0],[1,0,1],[0,1,0]]
Output:4
Explanation: Placing a post office at (1,1), the distance that post office to all the house sum is smallest.
Challenge
Solve this problem within O(n^3)
time.
- You cannot pass through wall and house, but can pass through empty.
- You only build post office on an empty.
思路:BFS,注意只有是0的时候,才能继续加入queue,而且还要判断最后visited的house的数目是否全部visite了
public class Solution {
/**
* @param grid: a 2D grid
* @return: An integer
*/
public int shortestDistance(int[][] grid) {
if(grid == null || grid.length == 0 || grid[0].length == 0) {
return -1;
}
int n = grid.length;
int m = grid[0].length;
int globalmin = Integer.MAX_VALUE;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(grid[i][j] == 0) {
int distance = bfsSearch(grid, i, j);
globalmin = Math.min(globalmin, distance);
}
}
}
return globalmin == Integer.MAX_VALUE ? -1 : globalmin;
}
private int bfsSearch(int[][] grid, int sx, int sy) {
if(grid == null || grid.length == 0 || grid[0].length == 0){
return -1;
}
int n = grid.length;
int m = grid[0].length;
boolean[][] visited = new boolean[n][m];
Queue<Integer> queueX = new LinkedList<Integer>();
Queue<Integer> queueY = new LinkedList<Integer>();
queueX.offer(sx);
queueY.offer(sy);
visited[sx][sy] = true;
int[] dx = {1,-1,0,0};
int[] dy = {0,0,1,-1};
int step = 0;
int stepCount = 0;
while(!queueX.isEmpty()){
int size = queueX.size();
while(size > 0) {
int x = queueX.poll();
int y = queueY.poll();
size--;
for(int k = 0; k < 4; k++) {
int nx = x + dx[k];
int ny = y + dy[k];
if(isvalid(nx, ny, grid, visited)){
visited[nx][ny] = true;
if(grid[nx][ny] == 1) {
stepCount += step+1;
}
if(grid[nx][ny] == 0) {
queueX.offer(nx);
queueY.offer(ny);
}
}
}
}
step++;
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++){
if(grid[i][j] == 1 && !visited[i][j]){
return Integer.MAX_VALUE;
}
}
}
return stepCount;
}
private boolean isvalid(int nx, int ny, int[][] grid, boolean[][] visited) {
int n = grid.length;
int m = grid[0].length;
return (0 <= nx && nx < n && 0 <= ny && ny < m
&& grid[nx][ny] != 2 && !visited[nx][ny]);
}
}