3341.到达最后一个房间的最少时间I
Dijkstra, https://leetcode.cn/problems/find-minimum-time-to-reach-last-room-i/
有一个地窖,地窖中有 n x m 个房间,它们呈网格状排布。
给你一个大小为 n x m 的二维数组 moveTime ,其中 moveTime[i][j] 表示在这个时刻 以后 你才可以 开始 往这个房间 移动 。你在时刻 t = 0 时从房间 (0, 0) 出发,每次可以移动到 相邻 的一个房间。在 相邻 房间之间移动需要的时间为 1 秒。
请你返回到达房间 (n - 1, m - 1) 所需要的 最少 时间。
如果两个房间有一条公共边(可以是水平的也可以是竖直的),那么我们称这两个房间是 相邻 的。
示例 1:
输入:moveTime = [[0,4],[4,4]]
输出:6
解释:
需要花费的最少时间为 6 秒。
- 在时刻
t == 4,从房间(0, 0)移动到房间(1, 0),花费 1 秒。 - 在时刻
t == 5,从房间(1, 0)移动到房间(1, 1),花费 1 秒。
示例 2:
输入:moveTime = [[0,0,0],[0,0,0]]
输出:3
解释:
需要花费的最少时间为 3 秒。
- 在时刻
t == 0,从房间(0, 0)移动到房间(1, 0),花费 1 秒。 - 在时刻
t == 1,从房间(1, 0)移动到房间(1, 1),花费 1 秒。 - 在时刻
t == 2,从房间(1, 1)移动到房间(1, 2),花费 1 秒。
示例 3:
输入:moveTime = [[0,1],[1,2]]
输出:3
提示:
2 <= n == moveTime.length <= 502 <= m == moveTime[i].length <= 500 <= moveTime[i][j] <= 10^9
思路分析
这是一个典型的 **最短路径问题。
- 不记录最短时间表,而是让优先队列自动保证我们最先到达终点
- 当访问一个节点时,我们才标记为已访问,确保最优路径被优先处理
python
import heapq
from typing import List
class Solution:
def minTimeToReach(self, moveTime: List[List[int]]) -> int:
n, m = len(moveTime), len(moveTime[0])
pq = [(0, 0, 0)] # (time, row, col)
visited = [[False]*m for _ in range(n)]
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
while pq:
time, r, c = heapq.heappop(pq)
if r == n-1 and c == m-1:
return time
if visited[r][c]:
continue
visited[r][c] = True
for dr, dc in directions:
nr, nc = r + dr, c + dc
if 0 <= nr < n and 0 <= nc < m and not visited[nr][nc]:
wait_time = max(time, moveTime[nr][nc])
heapq.heappush(pq, (wait_time + 1, nr, nc))
return -1⏱️ 时间复杂度分析
- 每个节点最多被访问一次,堆操作为
O(log nm) - 总体复杂度:
O(nm * log(nm)),适用于题目限制n,m ≤ 50