前往目标城市的最小费用
难度:
标签:
题目描述
代码结果
运行时间: 260 ms, 内存: 29.9 MB
/*
题目思路:
同样的问题,但这次使用Java Stream API来简化代码。
我们将Dijkstra算法中的一些操作替换为Stream操作。
*/
import java.util.*;
import java.util.stream.*;
class Solution {
public int minCost(int n, int[][] edges) {
// 使用优先队列和流操作来处理每个城市的最小费用
PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparingInt(a -> a[1]));
pq.offer(new int[]{0, 0});
// 初始化每个城市的最小费用
int[] minCost = IntStream.range(0, n).map(i -> Integer.MAX_VALUE).toArray();
minCost[0] = 0;
// 创建邻接表
List<List<int[]>> graph = Stream.generate(ArrayList<int[]>::new).limit(n).collect(Collectors.toList());
Arrays.stream(edges).forEach(edge -> graph.get(edge[0]).add(new int[]{edge[1], edge[2]}));
// Dijkstra算法
while (!pq.isEmpty()) {
int[] cur = pq.poll();
int city = cur[0];
int cost = cur[1];
if (city == n - 1) return cost;
if (cost > minCost[city]) continue;
graph.get(city).forEach(next -> {
int nextCity = next[0];
int nextCost = next[1] + cost;
if (nextCost < minCost[nextCity]) {
minCost[nextCity] = nextCost;
pq.offer(new int[]{nextCity, nextCost});
}
});
}
return -1; // 如果找不到到达目标城市的路径
}
}
解释
方法:
该题解使用了Dijkstra算法结合动态规划来解决最小费用寻路问题。首先,建立图的邻接表。然后,使用一个优先队列(通过heapq实现)来进行最小距离的贪心选择。维护一个二维数组dist,其中dist[i][j]表示到达节点i使用了j次折扣的最小费用。从源点开始,每次从优先队列中选出当前费用最小的点进行扩展,考虑两种情况:不使用折扣和使用折扣(如果剩余折扣次数大于0)。如果通过当前路线得到的新费用小于已记录的费用,则更新费用,并将新状态加入队列。如果到达终点,则返回当前的费用。若队列为空仍未到达终点,则返回-1表示无法到达。
时间复杂度:
O((E+V) * log(V) * D)
空间复杂度:
O(E + V * D)
代码细节讲解
🦆
在Dijkstra算法结合动态规划的实现中,如何确保每个节点的最小费用都得到正确更新,特别是在使用折扣的情况下?
▷🦆
你是如何决定何时使用折扣以及何时不使用折扣的?此决策是否基于某种优化逻辑?
▷🦆
为什么在更新节点费用时,需要考虑是否来自同一个父节点(if y == fa continue)?这一步是否对算法的正确性或效率有重要影响?
▷