K 站中转内最便宜的航班
难度:
标签:
题目描述
有 n
个城市通过一些航班连接。给你一个数组 flights
,其中 flights[i] = [fromi, toi, pricei]
,表示该航班都从城市 fromi
开始,以价格 pricei
抵达 toi
。
现在给定所有的城市和航班,以及出发城市 src
和目的地 dst
,你的任务是找到出一条最多经过 k
站中转的路线,使得从 src
到 dst
的 价格最便宜 ,并返回该价格。 如果不存在这样的路线,则输出 -1
。
示例 1:
输入: n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]] src = 0, dst = 2, k = 1 输出: 200 解释: 城市航班图如下 从城市 0 到城市 2 在 1 站中转以内的最便宜价格是 200,如图中红色所示。
示例 2:
输入: n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]] src = 0, dst = 2, k = 0 输出: 500 解释: 城市航班图如下 从城市 0 到城市 2 在 0 站中转以内的最便宜价格是 500,如图中蓝色所示。
提示:
1 <= n <= 100
0 <= flights.length <= (n * (n - 1) / 2)
flights[i].length == 3
0 <= fromi, toi < n
fromi != toi
1 <= pricei <= 104
- 航班没有重复,且不存在自环
0 <= src, dst, k < n
src != dst
代码结果
运行时间: 27 ms, 内存: 17.4 MB
// Java solution using Java Streams for finding the cheapest flight with at most K stops
// Streams are used to filter and map the flights
import java.util.Arrays;
import java.util.stream.Stream;
public class Solution {
public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {
// Initialize the distance array with a large value
int[] dp = new int[n];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[src] = 0;
// Iterate over the number of stops
for (int i = 0; i <= K; i++) {
// Make a copy of the current distance array
int[] temp = Arrays.copyOf(dp, n);
Stream.of(flights)
.filter(flight -> dp[flight[0]] != Integer.MAX_VALUE)
.forEach(flight -> {
int u = flight[0], v = flight[1], w = flight[2];
temp[v] = Math.min(temp[v], dp[u] + w);
});
dp = temp;
}
// Return the result
return dp[dst] == Integer.MAX_VALUE ? -1 : dp[dst];
}
}
解释
方法:
这个题解使用了最短路径的 Bellman-Ford 算法的思路。它通过动态规划的方式,在有限的中转次数内,逐步松弛图中的每条边,最终得到从起点到终点的最短路径。具体来说,使用两个数组 pre 和 cur 分别记录上一轮松弛后和当前正在松弛的每个点的最短距离。每一轮松弛时,都利用 BFS 的方式遍历当前能够到达的所有点,用 pre 数组的信息更新 cur 数组,并将所有被更新的点加入队列。当遍历完 k+1 轮后,cur[dst] 即为从 src 到 dst 的最短路径。
时间复杂度:
平均 O(ke),最坏 O(n^3)
空间复杂度:
O(n+e)
代码细节讲解
🦆
题解中提到使用了Bellman-Ford算法的思路,但是实际实现似乎涉及到BFS,这种结合BFS的方式是否标准或有何改进之处?
▷🦆
在每一轮松弛操作中,为什么需要将当前队列中所有节点都遍历一遍?这样做与传统Bellman-Ford算法有何区别?
▷🦆
题解中提到如果到达终点的距离仍为inf,则不存在最短路径,那么在什么情况下会发生这种情况?是否有可能是因为k设置的太小?
▷🦆
题解中使用了两个数组pre和cur来记录不同阶段的最短路径,这种方法与单个数组更新有何优势和劣势?
▷