1091. 二进制矩阵中的最短路径
题目:给你一个 n x n 的二进制矩阵 grid 中,返回矩阵中最短 畅通路径 的长度。如果不存在这样的路径,返回 -1 。
二进制矩阵中的 畅通路径 是一条从 左上角 单元格(即,(0, 0))到 右下角 单元格(即,(n - 1, n - 1))的路径,该路径同时满足下述要求:
路径途经的所有单元格的值都是 0 。 路径中所有相邻的单元格应当在 8 个方向之一 上连通(即,相邻两单元之间彼此不同且共享一条边或者一个角)。 畅通路径的长度 是该路径途经的单元格总数。
解题思路:
- 从左上角开始,将起始位置加入到队列中,并标记为已访问。
- 从队列中依次取出位置,探索其周围八个方向的相邻位置,如果相邻位置可通过且未被访问,则将其加入队列,并标记为已访问,并将其路径长度加1。
- 不断重复这个过程,直到达到右下角位置或者队列为空。
- 如果成功到达右下角,则返回路径长度;否则返回-1表示无法到达。
type coordinate struct {
x, y int
}
func shortestPathBinaryMatrix(grid [][]int) int {
n := len(grid)
if n == 0 {
return -1
}
m := len(grid[0])
if grid[0][0] == 1 || grid[n-1][m-1] == 1 {
return -1
}
queue := list.List{}
queue.PushBack(coordinate{
x: 0,
y: 0,
})
var visitedMap = make(map[coordinate]bool)
visitedMap[coordinate{
x: 0,
y: 0,
}] = true
directions := [][]int{{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}}
var steps = 1
for queue.Len() > 0 {
size := queue.Len()
for i := 0; i < size; i++ {
curr := queue.Remove(queue.Front()).(coordinate)
if curr.x == m-1 && curr.y == n-1 {
return steps
}
for _, dir := range directions {
next := coordinate{
x: curr.x + dir[0],
y: curr.y + dir[1],
}
// 有效&&未访问
if isValid(next, grid) && !visitedMap[next] {
queue.PushBack(next)
visitedMap[next] = true
}
}
}
steps++
}
return -1
}
func isValid(c coordinate, grid [][]int) bool {
n := len(grid)
return c.x >= 0 && c.x < n && c.y >= 0 && c.y < n && grid[c.x][c.y] == 0
}