2662. 前往目标的最小代价
难度:中等
时间:2023/05/05
给你一个数组 start ,其中 start = [startX, startY] 表示你的初始位置位于二维空间上的 (startX, startY) 。另给你一个数组 target ,其中 target = [targetX, targetY] 表示你的目标位置 (targetX, targetY) 。
从位置 (x1, y1) 到空间中任一其他位置 (x2, y2) 的代价是 |x2 - x1| + |y2 - y1| 。
给你一个二维数组 specialRoads ,表示空间中存在的一些特殊路径。其中 specialRoads[i] = [x1i, y1i, x2i, y2i, costi] 表示第 i 条特殊路径可以从 (x1i, y1i) 到 (x2i, y2i) ,但成本等于 costi 。你可以使用每条特殊路径任意次数。
返回从 (startX, startY) 到 (targetX, targetY) 所需的最小代价。
示例 1:
输入:start = [1,1], target = [4,5], specialRoads = [[1,2,3,3,2],[3,4,4,5,1]]
输出:5
解释:从 (1,1) 到 (4,5) 的最优路径如下:
- (1,1) -> (1,2) ,移动的代价是 |1 - 1| + |2 - 1| = 1 。
- (1,2) -> (3,3) ,移动使用第一条特殊路径,代价是 2 。
- (3,3) -> (3,4) ,移动的代价是 |3 - 3| + |4 - 3| = 1.
- (3,4) -> (4,5) ,移动使用第二条特殊路径,代价是 1 。
总代价是 1 + 2 + 1 + 1 = 5 。
可以证明无法以小于 5 的代价完成从 (1,1) 到 (4,5) 。
示例 2:
输入:start = [3,2], target = [5,7], specialRoads = [[3,2,3,4,4],[3,3,5,5,5],[3,4,5,6,6]]
输出:7
解释:最优路径是不使用任何特殊路径,直接以 |5 - 3| + |7 - 2| = 7 的代价从初始位置到达目标位置。
提示:
start.length == target.length == 21 <= startX <= targetX <= 10^51 <= startY <= targetY <= 10^51 <= specialRoads.length <= 200specialRoads[i].length == 5startX <= x1i, x2i <= targetXstartY <= y1i, y2i <= targetY1 <= costi <= 10^5
解题思路:
Dijkstra算法包括两个主要步骤:节点的选择和距离更新。
节点的选择:在每次选择最短距离的节点时,需要遍历所有节点,这个操作的时间复杂度是 O(n)。 距离更新:对于每个节点,需要更新所有与其相邻的节点的距离。由于使用了优先队列来存储待处理的节点,每次从堆中取出距离最短的节点的操作的时间复杂度是 O(log n)。而对于每个节点,需要更新其相邻节点的距离,这个操作的时间复杂度是 O(m)。
class Solution:
def minimumCost(self, start: List[int], target: List[int], specialRoads: List[List[int]]) -> int:
t = tuple(target)
dis = defaultdict(lambda: inf)
dis[tuple(start)] = 0
vis = set()
while True:
v, dv = None, -1
for p, d in dis.items():
if p not in vis and (dv < 0 or d < dv):
v, dv = p, d
if v == t: return dv
vis.add(v)
vx, vy = v
dis[t] = min(dis[t], dv + t[0] - vx + t[1] - vy)
for x1, y1, x2, y2, cost in specialRoads:
w = (x2,y2)
dis[w] = min(dis[w], dv + abs(x1 - vx) + abs(y1 - vy) + cost)