java - 难以弄清楚为什么我的 Dijkstra 算法的实现不起作用?
问题描述
我正在使用 Dijkstra 的算法来解决 Leetcode 问题网络延迟时间(https://leetcode.com/problems/network-delay-time),在这里我尝试找到将信号从起始顶点传播到其他每个顶点的最小成本加权图中的顶点。我下面的代码通过了 31/52 的测试用例,但未通过以下测试用例。
我对为什么我的代码失败感到非常困惑,因为我相信我正确地实现了 Dijkstra 算法的所有组件。如果有人能指出我可能的错误点,那将不胜感激:
[[15,8,1],[7,10,41],[7,9,34],[9,4,31],[12,13,50],[14,3,52],[4,11,99],[4,7,86],[10,13,57],[9,6,10],[1,7,51],[7,15,38],[1,9,11],[12,7,94],[9,13,34],[11,7,79],[7,6,28],[5,3,34],[2,6,97],[14,1,97],[6,10,90],[12,10,37],[13,3,73],[11,14,7],[15,1,39],[6,5,90],[13,6,43],[6,9,32],[4,6,45],[11,10,2],[2,13,4],[14,15,29],[1,14,88],[14,6,19],[6,2,29],[3,14,72],[1,15,4],[11,5,2],[6,7,56],[8,7,88],[13,14,70],[14,12,58],[14,2,86],[11,3,57],[5,2,56],[3,10,26],[2,11,21],[14,5,54],[5,12,40],[14,4,81],[15,2,99],[5,7,57],[13,12,5],[4,9,60],[12,15,48],[6,14,1],[9,7,44],[13,7,69],[5,13,42],[4,1,7],[11,9,76],[8,1,76],[5,14,29],[2,3,69],[7,3,23],[12,14,28],[11,4,85],[10,1,10],[15,12,36],[1,11,69],[15,10,96],[11,13,69],[7,12,49],[1,2,95],[6,4,46],[8,12,94],[12,4,93],[13,5,31],[12,2,60],[6,1,87],[4,14,20],[5,11,89],[4,15,88],[4,10,21],[1,6,5],[10,8,26],[8,2,51],[3,15,23],[7,2,12],[11,1,47],[2,1,75],[3,8,63],[8,10,19],[6,8,18],[4,2,55],[14,11,80],[10,3,73],[3,5,22],[12,3,61],[1,13,33],[9,3,98],[9,12,69],[15,9,6],[7,13,76],[11,12,22],[11,15,51],[13,15,46],[5,10,58],[1,10,26],[13,4,85],[7,14,58],[5,8,46],[11,6,32],[10,9,41],[9,14,35],[14,13,60],[3,9,97],[2,5,39],[7,11,19],[1,12,27],[7,5,13],[8,4,34],[9,15,25],[5,1,93],[15,13,97],[14,9,35],[8,6,67],[9,5,39],[13,11,35],[7,4,21],[12,9,64],[14,8,8],[10,12,94],[8,9,76],[8,5,71],[2,9,64],[10,14,59],[1,4,74],[7,1,69],[15,5,55],[6,15,80],[13,8,84],[8,13,63],[8,3,91],[10,4,87],[1,5,39],[8,11,0],[1,3,79],[4,5,82],[4,12,87],[3,11,29],[7,8,92],[10,7,77],[6,12,42],[13,2,40],[9,10,13],[4,13,65],[2,4,34],[3,13,44],[2,14,69],[3,4,42],[5,15,98],[14,7,6],[15,3,94],[10,2,37],[15,11,7],[9,2,15],[13,9,66],[4,8,83],[8,15,23],[13,1,50],[6,13,57],[2,10,37],[10,6,38],[2,7,45],[9,8,8],[3,12,28],[3,2,83],[2,12,75],[1,8,91],[4,3,70],[12,6,48],[3,1,13],[5,6,42],[6,11,96],[3,6,22],[15,6,34],[11,8,43],[15,7,40],[9,11,57],[11,2,11],[2,8,22],[9,1,73],[2,15,40],[12,11,10],[15,4,78],[12,8,75],[10,15,37],[13,10,44],[8,14,33],[3,7,82],[5,4,46],[12,5,79],[15,14,43],[10,5,65],[5,9,34],[12,1,54],[6,3,16],[14,10,83],[10,11,67]]
15
8
下面是我的Java代码:
class Solution {
// Dijkstra's Algorithm:
// Time: O(|V| + |E| log(|V|)), since I used a min-heap.
// Space: O(|V| + |E|)
public int networkDelayTime(int[][] times, int n, int k) {
// Represent the graph as an adjacency list.
// Source Node -> set of destination Pairs (Target Node, Travel Time).
HashMap<Integer, HashSet<Pair<Integer, Integer>>> adjacencyList = new HashMap<Integer, HashSet<Pair<Integer, Integer>>>();
for (int[] time : times) {
int source = time[0];
int target = time[1];
int travelTime = time[2];
// Retrieve the existing set of destination.
HashSet<Pair<Integer, Integer>> destinationSet = adjacencyList.getOrDefault(source, new HashSet<Pair<Integer, Integer>>());
destinationSet.add(new Pair<Integer, Integer>(target, travelTime));
// Update the set of destinations that can be reached from the current source.
adjacencyList.put(source, destinationSet);
}
// Map the distance from source to vertex v.
HashMap<Integer, Integer> distFromSource = new HashMap<Integer, Integer>();
// Backtracking purposes: map each vertex to the previous vertex along the shortest path.
HashMap<Integer, Integer> prevVertex = new HashMap<Integer, Integer>();
// Min-heap which stores the vertexes, based on their distance
// from the source.
PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>((v1, v2) -> distFromSource.get(v1) - distFromSource.get(v2));
// Edge Case: distance from source to source is 0.
distFromSource.put(k, 0);
// Initially, the distance from the source to each vertex is infinite (except for source itself).
// We also haven't figured out any of the previous vertexes.
for (int i = 1; i <= n; i++) {
if (i != k) {
distFromSource.put(i, Integer.MAX_VALUE);
prevVertex.put(i, -1);
}
minHeap.add(i);
}
// Store the visited vertices so we don't visit them again.
HashSet<Integer> visited = new HashSet<Integer>();
// While are min heap still isn't empty.
while (!minHeap.isEmpty()) {
// Retrieve the closest vertex to the source.
Integer closestVertex = minHeap.poll();
// Check that the closest vertex hasn't already been visited.
if (!visited.contains(closestVertex)) {
// Mark the vertex as visited.
visited.add(closestVertex);
// Retrieve the distance to the closest vertex.
int distToClosestVertex = distFromSource.get(closestVertex);
// Go through the edges to the closest vertex's neighbors.
for (Pair<Integer, Integer> edge : adjacencyList.getOrDefault(closestVertex, new HashSet<Pair<Integer, Integer>>())) {
int destination = edge.getKey();
int travelTime = edge.getValue();
int alternativeDist = distToClosestVertex + travelTime;
// If we have found a new shortest path to the destination.
if (alternativeDist < distFromSource.get(destination)) {
distFromSource.put(destination, alternativeDist);
prevVertex.put(destination, closestVertex);
}
}
}
}
// Find the maximum distance to any one of the nodes.
int maxDistance = Integer.MIN_VALUE;
for (Integer dist : distFromSource.values()) {
// We are unable to send the singal to every vertex.
if (dist == Integer.MAX_VALUE) {
return -1;
}
maxDistance = Math.max(maxDistance, dist);
}
return maxDistance;
}
}
解决方案
推荐阅读
- python - - 不支持的操作数类型:“NoneType”和“datetime.datetime”
- python - 使用python连接到MariaDB时出现sql语法错误
- swift - swift - primaryActionTriggered - 发件人问题
- tmux - tmux 8 窗格“理智”平铺布局
- javascript - 如何删除 dropzone 缩略图上的文件大小和/或文件名
- java - AspectJ 在使用周围建议和 ProceedingJoinPoint 时遇到问题
- google-apps-script - Google Apps 脚本将值设置为多个单元格
- google-apps-script - Google Apps 脚本,复制格式 - 仍然无法正常工作
- c# - 基于C#中的CheckBox排序
- c# - 如何在 WPF 中将属性名称转换为框架元素?