题目
https://leetcode-cn.com/problems/shortest-path-in-binary-matrix/
在一个 N × N
的方形网格中,每个单元格有两种状态:空(0)或者阻塞(1)。
一条从左上角到右下角、长度为 k
的畅通路径,由满足下述条件的单元格 C_1, C_2, ..., C_k
组成:
相邻单元格 C_i
和 C_{i+1}
在八个方向之一上连通(此时,C_i
和 C_{i+1}
不同且共享边或角)
C_1
位于 (0, 0)
(即,值为 grid[0][0]
)
C_k
位于 (N-1, N-1)
(即,值为 grid[N-1][N-1]
)
如果 C_i
位于 (r, c)
,则 grid[r][c]
为空(即,grid[r][c] == 0
)
返回这条从左上角到右下角的最短畅通路径的长度。如果不存在这样的路径,返回 -1 。
BFS
起点为(0,0)
点,终点为(rows - 1, cols - 1)
。需要计算从起点到终点的最短距离,类似于二叉树的层序遍历,首先在队列中加入起点,然后判断当前队列的大小,每次取一层的节点后再放入一层的节点,每次遍历新的一层节点时使变量count++
用来记录当前走了几步,当到达终点时直接返回。需要注意边界值,也就是起点或终点被阻塞时直接返回-1。
class Solution {
int[][] dirs = new int[][]{{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,-1},{-1,1},{1,-1}};
public int shortestPathBinaryMatrix(int[][] grid) {
int rows = grid.length;
int cols = grid[0].length;
if (grid[0][0] == 1 || grid[rows-1][cols-1] == 1)
return -1;
boolean[][] seen = new boolean[rows][cols];
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{0, 0});
seen[0][0] = true;
int count = 0;
int minLen = Integer.MAX_VALUE;
while (!queue.isEmpty()) {
int size = queue.size();
count++;
while (size-- > 0) {
int[] cur = queue.poll();
int x = cur[0];
int y = cur[1];
if (x == rows - 1 && y == cols - 1) {
return count;
}
for (int[] dir : dirs) {
int nx = x + dir[0];
int ny = y + dir[1];
if (nx < 0 || nx >= rows || ny < 0 || ny >= cols
|| seen[nx][ny] || grid[nx][ny] == 1) continue;
queue.offer(new int[]{nx, ny});
seen[nx][ny] = true;
}
}
}
return -1;
}
}