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;
}}