
2025-04-17:穿越网格图的安全路径。用go语言,给定一个大小为 m 行 n 列的二维二进制数组 grid,以及一个初始健康值 health。
你从左上角的位置 (0, 0) 出发,目标是抵达右下角的位置 (m - 1, n - 1)。
在移动时,你可以选择上下左右四个方向的相邻格子,但前提是移动后你的健康值始终保持大于0。
如果你进入的格子 grid[i][j] 为 1,则表示该格子存在危险,会减少你当前的健康值 1 点。
请判断是否存在一条路径,使你能够从起点走到终点且在终点时健康值仍然是正数。
如果可以达到,返回 true,否则返回 false。
m == grid.length。
n == grid[i].length。
1 <= m, n <= 50。
2 <= m * n。
1 <= health <= m + n。
grid[i][j] 要么是 0 ,要么是 1 。
输入:grid = [[0,1,0,0,0],[0,1,0,1,0],[0,0,0,1,0]], health = 1 。
输出:true 。
解释:
沿着下图中灰色格子走,可以安全到达最终的格子。

题目来自leetcode3286。
dis,用于记录从起点 (0,0) 到每个位置所消耗的最少健康值(即走过的格子中“1”的数量)。dis 值为极大数(表示未访问或尚无更优路径)。dis 初始化为 grid[0][0] (因为开始位置如果是“1”,健康值就先减1)。health,如果达到及以上,直接跳过(因为健康值已经不够,不能继续走这条路径)。true。true,说明没有找到满足健康值条件的路径,返回 false。dis 数组来避免多余的更新,减少了重复搜索。dis 二维数组记录状态,大小为 m * n,空间是 O(m * n)。综上,总的时间复杂度和空间复杂度均为 O(m * n)。
package main
import (
"fmt"
"math"
)
func findSafeWalk(grid [][]int, health int) bool {
type pair struct{ x, y int }
dirs := []pair{{0, -1}, {0, 1}, {-1, 0}, {1, 0}}
m, n := len(grid), len(grid[0])
dis := make([][]int, m)
for i := range dis {
dis[i] = make([]int, n)
for j := range dis[i] {
dis[i][j] = math.MaxInt
}
}
dis[0][0] = grid[0][0]
q := [2][]pair{{{}}} // 两个 slice 头对头来实现 deque
for {
var p pair
if len(q[0]) > 0 {
p, q[0] = q[0][len(q[0])-1], q[0][:len(q[0])-1]
} else {
p, q[1] = q[1][0], q[1][1:]
}
i, j := p.x, p.y
if dis[i][j] >= health {
return false
}
if i == m-1 && j == n-1 {
return true
}
for _, d := range dirs {
x, y := i+d.x, j+d.y
if 0 <= x && x < m && 0 <= y && y < n {
cost := grid[x][y]
if dis[i][j]+cost < dis[x][y] {
dis[x][y] = dis[i][j] + cost
q[cost] = append(q[cost], pair{x, y})
}
}
}
}
}
func main() {
grid := [][]int{{0,1,0,0,0},{0,1,0,1,0},{0,0,0,1,0}}
health := 1
results := findSafeWalk(grid, health)
fmt.Println(results)
}

# -*-coding:utf-8-*-
from collections import deque
import sys
def find_safe_walk(grid, health):
dirs = [(0, -1), (0, 1), (-1, 0), (1, 0)]
m, n = len(grid), len(grid[0])
dis = [[sys.maxsize] * n for _ in range(m)]
dis[0][0] = grid[0][0]
# 使用两个双端队列模拟0-1 BFS的deque
q = [deque(), deque()]
q[dis[0][0]].append((0, 0))
while q[0] or q[1]:
if q[0]:
i, j = q[0].pop()
else:
i, j = q[1].popleft()
if dis[i][j] >= health:
return False
if i == m - 1 and j == n - 1:
return True
for dx, dy in dirs:
x, y = i + dx, j + dy
if 0 <= x < m and 0 <= y < n:
cost = grid[x][y]
if dis[i][j] + cost < dis[x][y]:
dis[x][y] = dis[i][j] + cost
q[cost].append((x, y))
return False
if __name__ == "__main__":
grid = [
[0,1,0,0,0],
[0,1,0,1,0],
[0,0,0,1,0],
]
health = 1
result = find_safe_walk(grid, health)
print(result)