Shortest Distance from All Buildings

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.

BFS

Time Complexity
O(kmn)
Space Complexity
O(mn)

思路

First, we need to clarify if it must has a place that can access to every house in matrix.

If it is not, we can improve our code by checking after each BFS, if there is still 0 in the grid and still hasn't visited, if there is, it means these 0 can't be the post office. Then we can turn these 0 into 2 as walls. So we don't need to count these 0 into cost any more.

Put all 1 into queue do BFS. We need to keep a global matrix called cost and add the distance from each 1 by doing BFS.

Each 1 need a new matrix for checking visited but we can keep only one matrix here to save space.

At last, checking cost matrix to find the min distance.

代码

public int shortestDistance(int[][] grid) {
    // Write your code here
    //corner case
    if(grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0) return 0;
    
    int rows = grid.length, cols = grid[0].length;
    int[][] directions = new int[][]{{-1,0},{1,0},{0,1},{0,-1}};
    int[][] cost = new int[rows][cols];
    
    for(int i = 0; i < rows; i++){
        for(int j = 0; j < cols; j++){
            if(grid[i][j] == 1){
                bfs(grid, cost, i, j, rows, cols, directions);
            }
        }
    }
    
    int minDis = Integer.MAX_VALUE;
    for(int i = 0; i < rows; i++){
        for(int j = 0; j < cols; j++){
            if(grid[i][j] == 0 && cost[i][j] != 0){
                minDis = Math.min(cost[i][j], minDis);
            }
        }
    }
    return minDis == Integer.MAX_VALUE ? -1 : minDis;
}
    
    private void bfs(int[][] grid, int[][] cost, int i, int j, int rows, int cols, int[][] directions){
        Queue<int[]> queue = new LinkedList<int[]>();
        queue.offer(new int[]{i, j});
        boolean[][] visited = new boolean[rows][cols];
        visited[i][j] = true;
        int distance = 1;
        
        while(!queue.isEmpty()){
            int size = queue.size();
            for(int k = 0; k < size; k++){
                int[] cur = queue.poll();
                for(int[] dir : directions){
                    int x = cur[0] + dir[0];
                    int y = cur[1] + dir[1];
                    
                    if(x >= 0 && x < rows && y >= 0 && y < cols && visited[x][y] == false && grid[x][y] == 0){
                            queue.offer(new int[]{x, y});
                            visited[x][y] = true;
                            cost[x][y] += distance;
                    }
                }
            }
            distance ++;
        }
        
        for(int r = 0; r < rows; r++){
            for(int c = 0; c < cols; c++){
                if(grid[r][c] == 0 && visited[r][c] == false){
                    grid[r][c] = 2;
                }
            }
        }
    }

annielulu
5 声望5 粉丝