逃离火灾
难度:
标签:
题目描述
给你一个下标从 0 开始大小为 m x n
的二维整数数组 grid
,它表示一个网格图。每个格子为下面 3 个值之一:
0
表示草地。1
表示着火的格子。2
表示一座墙,你跟火都不能通过这个格子。
一开始你在最左上角的格子 (0, 0)
,你想要到达最右下角的安全屋格子 (m - 1, n - 1)
。每一分钟,你可以移动到 相邻 的草地格子。每次你移动 之后 ,着火的格子会扩散到所有不是墙的 相邻 格子。
请你返回你在初始位置可以停留的 最多 分钟数,且停留完这段时间后你还能安全到达安全屋。如果无法实现,请你返回 -1
。如果不管你在初始位置停留多久,你 总是 能到达安全屋,请你返回 109
。
注意,如果你到达安全屋后,火马上到了安全屋,这视为你能够安全到达安全屋。
如果两个格子有共同边,那么它们为 相邻 格子。
示例 1:
输入:grid = [[0,2,0,0,0,0,0],[0,0,0,2,2,1,0],[0,2,0,0,1,2,0],[0,0,2,2,2,0,2],[0,0,0,0,0,0,0]] 输出:3 解释:上图展示了你在初始位置停留 3 分钟后的情形。 你仍然可以安全到达安全屋。 停留超过 3 分钟会让你无法安全到达安全屋。
示例 2:
输入:grid = [[0,0,0,0],[0,1,2,0],[0,2,0,0]] 输出:-1 解释:上图展示了你马上开始朝安全屋移动的情形。 火会蔓延到你可以移动的所有格子,所以无法安全到达安全屋。 所以返回 -1 。
示例 3:
输入:grid = [[0,0,0],[2,2,0],[1,2,0]] 输出:1000000000 解释:上图展示了初始网格图。 注意,由于火被墙围了起来,所以无论如何你都能安全到达安全屋。 所以返回 109 。
提示:
m == grid.length
n == grid[i].length
2 <= m, n <= 300
4 <= m * n <= 2 * 104
grid[i][j]
是0
,1
或者2
。grid[0][0] == grid[m - 1][n - 1] == 0
代码结果
运行时间: 132 ms, 内存: 19.2 MB
解释
方法:
此题解采用了双重宽度优先搜索(BFS)策略,首先对火的扩散进行模拟,然后模拟人的移动,检查是否能安全到达目的地。首先初始化一个与网格大小相同的数组 fire_minutes 来记录火到达每个格子的时间。使用一个队列 q 来存放初始的火的位置,并将对应的 fire_minutes 设为 0。使用 BFS 扩散火,更新 fire_minutes 数组。完成后,使用第二个 BFS 从起点开始,模拟人的移动。比较当前位置的时间与火到达时间,以决定是否能移动到该位置。若能到达终点,则记录并尝试寻找最大停留时间。若在 BFS 过程中发现火将完全阻挡去路,则返回 -1。最终,如果总是能安全到达,返回 109。
时间复杂度:
O(m*n)
空间复杂度:
O(m*n)
代码细节讲解
🦆
在双重宽度优先搜索策略中,首先进行的是火的扩散模拟。请问为什么选择先模拟火的扩散而不是人的移动?
▷🦆
在题解中提到,如果总是能安全到达,则返回 109。请问如何判断“总是能安全到达”的条件是什么?
▷🦆
在火的扩散过程中,为何只考虑火扩散到草地(grid 值为 0 的格子)而不是墙或已经着火的格子?
▷🦆
在处理人的移动逻辑时,题解中使用了 `visit` 数组来防止重复访问,这种做法是否会遗漏一些可能的路径,尤其是当火的扩散改变了可行路径时?
▷