# [1091] 二进制矩阵中的最短路径
给你一个 n x n 的二进制矩阵 grid 中,返回矩阵中最短 畅通路径 的长度。如果不存在这样的路径,返回 -1 。
二进制矩阵中的 畅通路径 是一条从 左上角 单元格(即,(0, 0))到 右下角 单元格(即,(n - 1, n - 1))的路径,该路径同时满足下述要求:
路径途经的所有单元格都的值都是 0 。
路径中所有相邻的单元格应当在 8 个方向之一 上连通(即,相邻两单元之间彼此不同且共享一条边或者一个角)。
畅通路径的长度 是该路径途经的单元格总数。
示例 1:
输入:grid = [[0,1],[1,0]]
输出:2
示例 2:
输入:grid = [[0,0,0],[1,1,0],[1,1,0]]
输出:4
示例 3:
输入:grid = [[1,0,0],[1,1,0],[1,1,0]]
输出:-1
提示:
n == grid.length
n == grid[i].length
grid[i][j] 为 0 或 1
这道题也是一道比较典型的BFS题型。一道二维数组的BFS题型。
题目要求路径方向可以为8个方向,因此我们需要构建的树为八叉树,方向数组长度为8。
接下来就可以参考广度优先搜索专题里的通用思路来组织代码了。
function shortestPathBinaryMatrix(grid: number[][]): number {
const width = grid[0].length;
if (width === 0) return 0;
if (grid[0][0] === 1) return -1;
// 八个方向的方向数组
const directions = [
[0, 1],
[0, -1],
[1, 0],
[-1, 0],
[1, 1],
[-1, -1],
[1, -1],
[-1, 1]
];
const queue: [number, number][] = [[0, 0]];
let res = 1;
while (queue.length > 0) {
let len = queue.length;
while (len--) {
const [x, y] = queue.pop();
// 当遍历到终点时,返回树深度,即路径长度
if (x === width - 1 && y === width - 1) return res;
for (const [directX, directY] of directions) {
const currX = x + directX;
const currY = y + directY;
// 防止越界
if (currX < 0 || currX >= width || currY < 0 || currY >= width) continue;
// 防止重复与不可达搜索
if (grid[currX][currY] === 1) continue;
// 搜索完后就淹没掉该节点,防止重复入队
grid[currX][currY] = 1;
// 入队该子节点
queue.unshift([currX, currY]);
}
}
res += 1;
}
// 说明此时无可到终点的情况
return -1;
}