zoukankan      html  css  js  c++  java
  • leetcode 743 网络延迟时间 Dijkstra算法

      JAVA 暴力解法:

        public final int networkDelayTime(int[][] times, int n, int k) {
            Map<Integer, List<Integer[]>> map = new HashMap<Integer, List<Integer[]>>();
            for (int[] loads : times) {
                if (!map.containsKey(loads[0])) map.put(loads[0], new LinkedList<Integer[]>());
                map.get(loads[0]).add(new Integer[]{loads[1], loads[2]});
            }
            int re = -1;
            for (int i = 1; i <= n; i++) {
                if (i == k) continue;
                int curr = dfs(k, i, map, new HashSet<Integer>());
                if (curr == -1) return -1;
                re = Math.max(re, curr);
            }
            return re;
        }
    
        private final int dfs(int begin, int end, Map<Integer, List<Integer[]>> map, Set<Integer> loads) {
            if (begin == end) return 0;
            if (loads.contains(begin) || !map.containsKey(begin)) return -1;
            loads.add(begin);
            List<Integer[]> shortest = map.get(begin);
            int re = Integer.MAX_VALUE;
            for (Integer[] arr : shortest) {
                int curr = dfs(arr[0], end, map, loads);
                if (curr != -1) re = Math.min(re, curr + arr[1]);
            }
            loads.remove(begin);
            if (re == Integer.MAX_VALUE) re = -1;
            return re;
        }

      JAVA 暴力解法由自底向上转为自顶向下,方便剪枝:

        public final int networkDelayTime(int[][] times, int n, int k) {
            Map<Integer, List<Integer[]>> map = new HashMap<Integer, List<Integer[]>>();
            for (int[] time : times) {
                if (!map.containsKey(time[0])) map.put(time[0], new LinkedList<Integer[]>());
                map.get(time[0]).add(new Integer[]{time[1], time[2]});
            }
            int len = n + 1, re = -1;
            int[] reArr = new int[len];
            for (int i = 1; i < len; i++) reArr[i] = Integer.MAX_VALUE;
            search(reArr, map, k, 0);
            for (int i = 1; i < len; i++) {
                if (reArr[i] == Integer.MAX_VALUE) return -1;
                re = Math.max(re, reArr[i]);
            }
            return re;
        }
    
        private final void search(int[] reArr, Map<Integer, List<Integer[]>> map, int begin, int time) {
            if (time >= reArr[begin]) return;
            reArr[begin] = time;
            if (!map.containsKey(begin)) return;
            for (Integer[] next : map.get(begin)) search(reArr, map, next[0], time + next[1]);
        }

      在选择下一步的走法时,如果面临对所有可能性遍历的情况,就应该从缩小遍历集合的角度去优化这一步骤,贪心思维是非常好的思考角度。

      JAVA 贪心解法(Dijkstra算法 ):

    public final int networkDelayTime(int[][] times, int n, int k) {
            Map<Integer, List<Integer[]>> map = new HashMap<Integer, List<Integer[]>>();
            for (int[] time : times) {
                if (!map.containsKey(time[0])) map.put(time[0], new LinkedList<Integer[]>());
                map.get(time[0]).add(new Integer[]{time[1], time[2]});
            }
            int len = n + 1, re = -1;
            boolean[] isShortest = new boolean[len];
            int[] reArr = new int[len];
            for (int i = 1; i < len; i++) reArr[i] = Integer.MAX_VALUE;
            reArr[k] = 0;
            while (true) {
                int canNode = -1, shrotest = Integer.MAX_VALUE;
                for (int i = 1; i < len; i++) {
                    if (!isShortest[i] && reArr[i] < shrotest) {
                        shrotest = reArr[i];
                        canNode = i;
                    }
                }
                if (canNode == -1) break;
                isShortest[canNode] = true;
                if (map.containsKey(canNode))
                    for (Integer[] load : map.get(canNode)) reArr[load[0]] = Math.min(reArr[load[0]], shrotest + load[1]);
            }
            for (int i = 1; i < len; i++) {
                if (reArr[i] == Integer.MAX_VALUE) return -1;
                re = Math.max(re, reArr[i]);
            }
            return re;
        }

      JS 贪心解法(Dijkstra算法):

    var networkDelayTime = function (times, n, k) {
        let map = new Map(), len = n + 1, shortest = new Array(len), re = -1, isShortest = new Array(len);
        for (let i = 0; i < times.length; i++) {
            if (!map.has(times[i][0])) map.set(times[i][0], []);
            map.get(times[i][0]).push([times[i][1], times[i][2]]);
        }
        for (let i = 1; i < len; i++) shortest[i] = Number.MAX_VALUE;
        for (let i = 1; i < len; i++) isShortest[i] = false;
        shortest[k] = 0;
        while (true) {
            let currNode = -1, currShortest = Number.MAX_VALUE;
            for (let i = 0; i < len; i++) {
                if (!isShortest[i] && currShortest > shortest[i]) {
                    currShortest = shortest[i];
                    currNode = i;
                }
            }
            if (currNode === -1) break;
            isShortest[currNode] = true;
            let currNextArr = map.get(currNode);
            if (!currNextArr) continue;
            for (let i = 0; i < currNextArr.length; i++) shortest[currNextArr[i][0]] = Math.min(shortest[currNextArr[i][0]], currShortest + currNextArr[i][1]);
        }
        for (let i = 1; i < len; i++) {
            if (shortest[i] == Number.MAX_VALUE) return -1;
            re = Math.max(re, shortest[i]);
        }
        return re;
    };

      最终解法效果:

    当你看清人们的真相,于是你知道了,你可以忍受孤独
  • 相关阅读:
    HTML标签和属性三
    HTML标签和属性二
    HTML标签和属性一
    小程序相关面试题
    Vue路由的hash模式与history模式的区别?
    android中VideoView播放sd卡上面的视频
    Android中app开机自启动的开发
    java中byte,byte[]和int之间的转换
    Android多activity启动两种方式浅谈
    Android开发用到的几种常用设计模式浅谈(一):组合模式
  • 原文地址:https://www.cnblogs.com/niuyourou/p/14423782.html
Copyright © 2011-2022 走看看