刷
2019-July-08
和296的区别就是,有了障碍的存在,导致没法简单地纵向横向算距离= =
然后从每个点开始BFS,难点在于:
为了不走回头路,从一个点开始BFS的时候得标记走过的格子,需要一个新的boolean[m][n]的来标记,然后这个点走完需要reset
需要另一个int[m][n]来存每个点到各个HOUSE的距离,BFS的过程中更新。或许可以在原有的GRID上标记,比如用负数-1 -2代表距离,这样不至于和1 2搞混。
-1的情况怎么办?比如我有1 0 2 0 1这样被2隔开。这样每个点BFS完,不能简单的重新reset boolean[m][n]因为要遍历看看是不是所有点都VISIT了。
然后爆炸了。。
我看一刷的做法是用了个特别的flag
这个FLAG在BFS的时候代表我们正在给第几个HOURS进行BFS,然后用了负数便于区分1和2.
在原有的GRID上更新,在第一个点BFS后所有的0变成-1,代表被1个hourse BFS过了。
然后第二个点进行BFS的时候,找空地要看是不是 == -1 而不是0,。
第三个点就是 == -2
这样。。同时更新distanceGrid,这个用来存距离,遍历之后distanceGrid[i][j]代表IJ到所有点的距离
算总数的时候,比如总共8个点,只计算grid[i][j] == -8的点,-7, -6, -5 。。。说明有的房子没有BFS到,就是1 0 2 0 1这种情况,2个0都不是有效解
class Solution {
private static final int[] DIRECTIONS = new int[] {0, 1, 0, -1, 0};
public int shortestDistance(int[][] grid) {
if (grid == null || grid.length == 0 || grid[0].length == 0) return -1;
int[][] distanceGrid = new int[grid.length][grid[0].length];
int noXhourse = 0; // negative of No.n hourse
for (int i = 0; i < grid.length; i ++) {
for (int j = 0; j < grid[0].length; j ++) {
if (grid[i][j] == 1) {
bfs(i, j, distanceGrid, grid, noXhourse);
noXhourse --;
}
}
}
int res = Integer.MAX_VALUE;
for (int i = 0; i < grid.length; i ++) {
for (int j = 0; j < grid[0].length; j ++) {
// visited by X hourses
if (grid[i][j] == noXhourse) {
res = Math.min(res, distanceGrid[i][j]);
}
}
}
return res == Integer.MAX_VALUE ? -1 : res;
}
public void bfs(int i, int j, int[][] distanceGrid, int[][] grid, int noXhourse) {
ArrayDeque<int[]> q = new ArrayDeque<>();
q.offerLast(new int[] {i, j});
int distanceToIJ = 1;
while (!q.isEmpty()) {
int tempSize = q.size();
for (int k = 0; k < tempSize; k ++) {
int[] tempLocation = q.pollFirst();
int x = tempLocation[0];
int y = tempLocation[1];
for (int d = 0; d < 4; d ++) {
int nextX = x + DIRECTIONS[d];
int nextY = y + DIRECTIONS[d + 1];
if (nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length) continue;
if (grid[nextX][nextY] == noXhourse) {
distanceGrid[nextX][nextY] += distanceToIJ;
grid[nextX][nextY] = noXhourse - 1;
q.offerLast(new int[] {nextX, nextY});
}
}
}
distanceToIJ ++;
}
}
}