Amazon || Onsite || get a shortest manhattan distance in a given matrix
Anonymous User
1563

Given an matrix, we have three rooms, which are called, lock, unlock, guard, we can’t pass from locked room, but can pass from unlocked room. Write a function to get shortest Manhattan distance from every guard room to any unlocked room.

class Solution {
private int[] rowDir = {0, 0, 1, -1};
private int[] colDir = {1, -1, 0, 0};

public int shortestDistance(int[][] grid) {
    int rows = grid.length, cols = grid[0].length; 
    int[][] canReach = new int[rows][cols];
    int[][] distance = new int[rows][cols];
    if(grid == null || grid.length == 0 || grid[0].length == 0){
        return -1;
    }
    int totalBuilding = 0; 
    for(int i = 0; i < rows; i++){
        for(int j = 0; j < cols; j++){
            if(grid[i][j] == 1){
                totalBuilding++;
                bfs(grid, i, j, canReach, distance);  
            }
        }
    }
   
    int minDist = Integer.MAX_VALUE;
    for(int i = 0; i < rows; i++){
        for(int j = 0; j < cols; j++){
            if(canReach[i][j] == totalBuilding
              &&
              distance[i][j] < minDist){
                minDist = distance[i][j];
            }
        }
    }
    return minDist == Integer.MAX_VALUE ? -1 : minDist;
    
    
}

private void bfs(int[][] grid, int row, int col, int[][] canReach, int[][] distance){
    int rows = grid.length, cols = grid[0].length;
    Queue<int[]> q = new LinkedList<>();
    boolean[][] visited = new boolean[rows][cols];
    int dist = 0; 
    q.offer(new int[] {row, col});
    visited[row][col] = true;           
    while(!q.isEmpty()){
        dist ++;
        int size = q.size();
        for(int i = 0; i < size; i++){
           int[] cur = q.poll();
            for(int d = 0; d < 4; d++){
                int rr = rowDir[d] + cur[0];
                int cc = colDir[d] + cur[1];
                
                if(!isValid(grid, rr, cc, visited)) continue;
                
                visited[rr][cc] = true;
                q.offer(new int[]{rr, cc});
                distance[rr][cc] += dist;
                canReach[rr][cc]++;
            }
        }
    }
}

private boolean isValid(int[][] grid, int rr, int cc, boolean[][] visited){
    if(rr < 0 || rr > grid.length - 1 || cc < 0 || cc > grid[0].length - 1){
        return false;
    }
     if(visited[rr][cc]) return false;
    if(grid[rr][cc] != 0){
        return false;
    }
   
    return true;
}

}

Comments (3)