Medium
Do I really know what I was doing the first I do this problem?
Hell no!
Checked the answer again and started to get the feel of BFS.
这道题有个地方有点卡,就是为什么用BFS就确定每次遇到INF的点之后,第一次更新的距离就是离Gate的最近距离呢. 为什么有此疑问呢,因为我认为到INF的Gate可以有好多个,那么我们第一次check == ? INF时更新的那个INF to Gate的distance可能并不是最近的呀,那我们之后想要update的话怎么办呢,毕竟我们BFS的判断条件是==?INF呀,更新过后就是普通int了,所以看起来永远无法更新。然而事实就是不需要更新。
I had the same doubt as this person:
I don't see how this makes sure the shortest distance is found!
Once a room is discovered, it will not be traversed again (the == INF check), and thus will never get updated. What am I missing?
某个人解释得很好:
Here's my understanding of why this solution guarantees the shortest distance.
We can understand it by level-order BFS.
First we put all 0s to a queue, let's say these these 0s are in level 1. Then from each 0 of the queue, we will go up, down, left and right, all these positions that are rooms are at level 1, and so forth. So assume we only have Gate A and Gate B, and we have a room C and all the other positions are walls. Assume that distance between AC is 3 and distance between BC is 4. So for Gate A, room C is at its level 3, for Gate B, room C is at its level 4. Since we are doing level-order BFS, so C will always first be accessed by the gate that is closer to it, so it will be A.
Straightforwad的代码:
class Solution {
public void wallsAndGates(int[][] rooms) {
if (rooms == null || rooms.length == 0 || rooms[0].length == 0){
return;
}
int m = rooms.length;
int n = rooms[0].length;
Queue<int[]> queue = new LinkedList<>();
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
if (rooms[i][j] == 0){
queue.offer(new int[]{i,j});
}
}
}
while (!queue.isEmpty()){
int[] top = queue.poll();
int row = top[0];
int col = top[1];
if (row > 0 && col < n && rooms[row - 1][col] == Integer.MAX_VALUE){
rooms[row - 1][col] = rooms[row][col] + 1;
queue.offer(new int[]{row - 1, col});
}
if (row + 1 < m && col < n && rooms[row + 1][col] == Integer.MAX_VALUE){
rooms[row + 1][col] = rooms[row][col] + 1;
queue.offer(new int[]{row + 1, col});
}
if (col > 0 && rooms[row][col - 1] == Integer.MAX_VALUE){
rooms[row][col - 1] = rooms[row][col] + 1;
queue.offer(new int[]{row, col - 1});
}
if (col + 1 < n && col < n && rooms[row][col + 1] == Integer.MAX_VALUE){
rooms[row][col + 1] = rooms[row][col] + 1;
queue.offer(new int[]{row, col + 1});
}
}
}
}