This problem is different with 542. 01 Matrix and 286. Walls and Gates.

542 and 286 is once get the shortest path from one of the targets, then the cell's role is done.

317 need to sum up all shortest path from all targets. If we do it as the same way as 286, for every cell, you don't know whether it was visited from the same target of differnt target, so the following test case will fail:

[[1,2,0],[0,0,0],[0,0,0]]

Wroing Solution:

class Solution {
    public int shortestDistance(int[][] grid) {
        if(grid==null || grid.length==0)
            return 0;
        int m = grid.length, n = grid[0].length;
        int[][] count = new int[m][n];
        Queue<int[]> queue = new LinkedList<>();
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]==1){
                    queue.offer(new int[]{i,j});
                    grid[i][j]=-1;
                }else if(grid[i][j]==2){
                    grid[i][j]=-2;
                }
            }
        }
        
        int[][] dirs = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};
        int step=0;
        int buildNum = queue.size();
        while(!queue.isEmpty()){
            int size = queue.size();
            step++;
            for(int i=0;i<size;i++){
                int[] cell = queue.poll();
                for(int[] dir:dirs){
                    int x = cell[0]+dir[0];
                    int y = cell[1]+dir[1];
                    if(x<0||x>=m||y<0||y>=n||grid[x][y]==-1||grid[x][y]==-2)
                        continue;
                    if(grid[x][y]==0){
                        queue.offer(new int[]{x,y});
                        grid[x][y]=step;
                        count[x][y]=1;
                    }
                    else{
                        grid[x][y]+=step;
                        count[x][y]++;
                    }
                }
            }
        }
        
        int min = Integer.MAX_VALUE;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]>0 && count[i][j]==buildNum){
                    min = Math.min(min, grid[i][j]);
                }
            }
        }
        return min == Integer.MAX_VALUE?-1: min;
    }
}

The correct solution is, we BFS from every build one by one:

Time complexity (O(m*n*k), where k is the number of building.

class Solution {
    int buildNum=0;
    int[][] count ;
    Queue<int[]> queue = new LinkedList<>();
    public int shortestDistance(int[][] grid) {
        if(grid==null || grid.length==0)
            return 0;
        int m = grid.length, n = grid[0].length;
        count = new int[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]==1){
                   grid[i][j]=-1;
                    buildNum++;
                }else if(grid[i][j]==2)
                    grid[i][j]=-2;
            }
        }
        
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]==-1){
                    queue.offer(new int[]{i,j});
                    bfs(grid, i, j, m, n);
                }
            }
        }
        
        int min = Integer.MAX_VALUE;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]>0 && count[i][j]==buildNum){
                    min = Math.min(min, grid[i][j]);
                }
            }
        }
        return min == Integer.MAX_VALUE?-1: min;
    }
    
    private void bfs(int[][] grid, int i, int j, int m, int n){
        int[][] dirs = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};
        boolean[][] visited = new boolean[m][n];
        int step=0;
        while(!queue.isEmpty()){
            int size = queue.size();
            step++;
            for(int k=0;k<size;k++){
                int[] cell = queue.poll();
                for(int[] dir:dirs){
                    int x = cell[0]+dir[0];
                    int y = cell[1]+dir[1];
                    if(x<0||x>=m||y<0||y>=n||grid[x][y]==-1||grid[x][y]==-2||visited[x][y])
                        continue;
                    queue.offer(new int[]{x,y});
                    grid[x][y]+=step;
                    visited[x][y]=true;
                    count[x][y]++;
                }
            }
        }
    }
}

 

posted on 2022-03-09 11:50  阳光明媚的菲越  阅读(22)  评论(0编辑  收藏  举报