尝试使用优先级队列并使用哈希映射减少键在Java中实现Dijsktra

问题描述

全面披露-我正在执行此练习来解决Leetcode上的此问题-How do I create a Lambda layer using a simulated Lambda environment with Docker?

我发现此代码不适用于某些测试用例。我已经尝试调试了几个小时,还没有遇到任何运气。任何人都可以帮助解决此代码中的错误。


// this has a bug which I dont know how to find
  public int networkDelayTime(int[][] times,int N,int K) {
    Map<Integer,Map<Integer,Integer>> adjListWithDistance = new HashMap<>();
    // using this distance Map from K as comparator in priority queue
    Map<Integer,Integer> dMapFromK = new HashMap<>();

    PriorityQueue<Integer> pq = new PriorityQueue<>((k1,k2) -> dMapFromK.get(k1) - dMapFromK.get(k2));
    HashSet<Integer> v = new HashSet<>();


    for(int i = 0; i < times.length; i++){
      int source = times[i][0];
      int dest = times[i][1];
      int dist = times[i][2];

      adjListWithDistance.putIfAbsent(source,new HashMap<>());
      adjListWithDistance.get(source).put(dest,dist);
      //if(source == K){
      //    dMapFromK.put(dest,dist);
      //    pq.add(dest);
      // }
    }

    // distance from K to K is 0
    dMapFromK.put(K,0);
    pq.add(K);

    // we have already added all nodes from K to PQ,so we dont need to process K again
    //v.add(K);


    //System.out.println(adjListWithDistance);
    //System.out.println(dMapFromK);
    int res = 0;
    while(!pq.isEmpty()){
      int fromNode = pq.poll();
      if(v.contains(fromNode)) continue;
      v.add(fromNode);
      int curDist = dMapFromK.get(fromNode);
      res = curDist;
      //System.out.println("current node - " + fromNode);
      if(!adjListWithDistance.containsKey(fromNode)) {
        continue;
      }
      for(Integer toNode: adjListWithDistance.get(fromNode).keySet()){
        // BIG BUGGGGG,adding the below line is also causing a bug,not sure why
        if(v.contains(toNode)) continue;
        int toNodeDist = adjListWithDistance.get(fromNode).get(toNode);
        if(dMapFromK.containsKey(toNode) && dMapFromK.get(toNode) <= curDist + toNodeDist){
          continue;
        }else {
          if(!dMapFromK.containsKey(toNode)){
            dMapFromK.put(toNode,curDist + toNodeDist);

            // need to add map entry first before adding to priority queue else it throws an exception
            pq.offer(toNode);
          }else{
            dMapFromK.put(toNode,curDist + toNodeDist);
          }
        }
      }
    }
    System.out.println(adjListWithDistance);
    System.out.println(dMapFromK);
    if(dMapFromK.keySet().size() != N)
      return -1;
    //return res;
    return Collections.max(dMapFromK.values());
  }




TLDR:Dijsktra的此实现不正确,并且对于某些测试用例,不会返回某些节点的最短路径。我不确定为什么,我需要帮助调试我犯的错误。

解决方法

这几乎相同,将通过:

public final class Solution {
    public static final int networkDelayTime(
        final int[][] times,int n,final int k
    ) {
        Map<Integer,Map<Integer,Integer>> graph = new HashMap<>();

        for (final int[] node : times) {
            graph.putIfAbsent(node[0],new HashMap<>());
            graph.get(node[0]).put(node[1],node[2]);
        }

        Queue<int[]> queue = new PriorityQueue<>((a,b) -> (a[0] - b[0]));
        queue.add(new int[] {0,k});
        boolean[] visited = new boolean[n + 1];
        int total = 0;

        while (!queue.isEmpty()) {
            int[] curr = queue.remove();
            int currNode = curr[1];
            int currTime = curr[0];

            if (visited[currNode]) {
                continue;
            }

            visited[currNode] = true;
            total = currTime;
            n--;

            if (graph.containsKey(currNode)) {
                for (final int next : graph.get(currNode).keySet()) {
                    queue.add(new int[] {currTime + graph.get(currNode).get(next),next});
                }
            }
        }

        return n == 0 ? total : -1;
    }
}

如果您对此感兴趣,这是使用堆的Python版本:

from typing import List
import heapq
from collections import defaultdict

class Solution:
    def networkDelayTime(self,times: List[List[int]],n,k) -> int:
        queue = [(0,k)]
        graph = collections.defaultdict(list)
        memo = {}

        for u_node,v_node,time in times:
            graph[u_node].append((v_node,time))

        while queue:
            time,node = heapq.heappop(queue)
            if node not in memo:
                memo[node] = time
                for v_node,v_time in graph[node]:
                    heapq.heappush(queue,(time + v_time,v_node))
        return max(memo.values()) if len(memo) == n else -1

在C ++中,我们只使用一个快速整数类型:

// The following block might trivially improve the exec time;
// Can be removed;
static const auto __optimize__ = []() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(NULL);
    std::cout.tie(NULL);
    return 0;
}();

// Most of headers are already included;
// Can be removed;
#include <cstdint>
#include <vector>
#include <algorithm>


#define MAX INT_MAX
using ValueType = std::uint_fast16_t;

static const struct Solution {
    static const int networkDelayTime(
        const std::vector<vector<int>>& times,const int k
    ) {
        std::vector<ValueType> distances(n + 1,MAX);
        distances[k] = 0;

        for (ValueType index = 0; index < n; index++) {
            for (const auto& time : times) {
                const ValueType u_node = time[0];
                const ValueType v_node = time[1];
                const ValueType uv_weight = time[2];

                if (distances[u_node] != MAX && distances[v_node] > distances[u_node] + uv_weight) {
                    distances[v_node] = distances[u_node] + uv_weight;
                }
            }
        }

        ValueType total_time = 0;

        for (auto index = 1; index <= n; index++) {
            total_time = std::max(total_time,distances[index]);
        }

        return total_time == MAX ? -1 : total_time;
    }
};



参考文献

  • 有关其他详细信息,请参见Toast,在这里您可以找到许多具有各种Discussion Board且已被广泛接受的解决方案,包括低复杂度算法和渐近languages / {{ 3}}分析runtimememory

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...