2258.逃离火灾
【LetMeFly】2258.逃离火灾: 广度优先搜索BFS
力扣题目链接:https://leetcode.cn/problems/escape-the-spreading-fire/
给你一个下标从 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
方法一:二分 + BFS
首先以所有的🔥为起点开始广度优先搜索,这样我们就能得到“火焰燃烧图”(🔥燃烧到某个坐标所需耗时)。
接着可以二分“👱的开局等待时长”。假设开局等待时间为$t$,那么就从时间$t$开始对👱能到达的位置进行广度优先搜索。
在对👱的广搜过程中:
- 若搜索到了“安全屋”的位置:若“👱的到达耗时小于等于🔥的到达耗时”,则表示👱能等待时间$t$后再出发
- 否则(非安全屋位置):若“👱的到达耗时小于🔥的到达耗时”,则表示人能到达该位置
以上,即可。
- 时间复杂度$O(mn\log mn)$,其中$size(grid)=m\times n$
- 空间复杂度$O(mn)$
AC代码
C++
1 |
|
Python
1 |
|
方法二:数次BFS(无代码,可忽略)
其实这道题特殊的一点只有“安全屋”,只有安全屋这里🔥和👱可以同时到达。其他位置都必须保证👱比🔥严格地优先到达。
怎么到安全屋呢?要么从安全屋的左边,要么从安全屋的上面。因此先BFS一下得到🔥的“燃烧耗时图”,再按从$0$时刻出发BFS👱。
最后判断一下安全屋及其左上两个位置👱🔥的到达时间,即可推断出👱在起点最多待多久。
因$2^{15}>2\times10^4$,故方法一中也不会二分太多次。
同步发文于CSDN,原创不易,转载经作者同意后请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/134331955