package
0.0.0-20241220224003-b7cf03a90b2b
Repository: https://github.com/szhou12/leetcode-go.git
Documentation: pkg.go.dev
# README
787. Cheapest Flights Within K Stops
Solution idea
Method 1 - Dijkstra
要点总结
-
这道题的难点在于有中转站次数限制,找最省钱的路线我们知道可以用Dijkstra,但怎么把中转站次数限制这个信息融入到Dijkstra找最短路径的过程中呢?
- 突破点: 每个node记录双状态 -
[node label, # stops used]
- 到达一个node时, 不仅要关注这是哪一个node (node的位置, 用node label表示), 还要关注到达这个node时已经用掉了多少次中转 (# of stops used so far).
- i.e., node i = (i, stops)
- 这道题告诉我们: 一个node不是只能储存单条信息(node位置/node是谁),也可以储存多条信息. 就想DP不是只能一维,也可以有二维DP甚至更高维.
- 突破点: 每个node记录双状态 -
-
跟以往一维node的Dijkstra题目不太一样的是: 这道题Dijkstra return在loop里, 表示如果此时走到了终点, 那么第一次pop出来的一定是最短距离(并且满足中转站次数限制); 反之, 如果跳出了loop, 说明终点是无法到达的. return在loop里还有一个原因: 现在的code写法是如果到达一个node时刚好用掉k+1次, 会被跳过, 所以, 如果到达终点刚好要k+1次中转, 目前这样写的code不会记录到达终点所需的最小花费,反而保留-1表示无法到达. return在loop里还有另一个原因是: 这样写code简洁, 不需要收尾工作 (指输出时一个一个去查表格看dst 用掉几次中转花费最少)
- 这样写还有一个值得学习的地方: Dijkstra算法的物理意义就是第一次pop出来的一定是最短距离, 所以第一次pop出来终点就说明已经找到答案, 直接return就好了, 不用等到loop结束跳出
-
实现细节: 题目给的
k
表示起点和终点之间的中转站次数, 它没有包含跳到终点的最后一步. 所以, 实际上的限制应该是k+1
, 表示从起点最多跳k+1
步到达终点.
Time complexity = $O(E\log E)$