网络延迟时间

网络延迟时间

有 N 个网络节点,标记为 1 到 N。

给定一个列表 times,表示信号经过有向边的传递时间。 times[i] = (u, v, w),其中 u 是源节点,v 是目标节点, w 是一个信号从源节点传递到目标节点的时间。

现在,我们向当前的节点 K 发送了一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1。

注意:

N 的范围在 [1, 100] 之间。
K 的范围在 [1, N] 之间。
times 的长度在 [1, 6000] 之间。
所有的边 times[i] = (u, v, w) 都有 1 <= u, v <= N 且 0 <= w <= 100。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/network-delay-time
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

一开始的想法:

    public int networkDelayTime(int[][] times, int N, int K) {
        Set<Integer> set = new HashSet<>(N);
        int[] dist = new int[N + 1];
        for (int i = 0; i < dist.length; i++) {
            dist[i] = Integer.MAX_VALUE;
        }
        dist[K] = 0;
        for (int i = 0; i < N; i++) {
            set.add(K);
            for (int j = 0; j < times.length; j++) {
                if (times[j][0] == K && !set.contains(times[j][1]))
                    if (times[j][2] + dist[K] < dist[times[j][1]])
                        dist[times[j][1]] = times[j][2] + dist[K];
            }
            for (int j = 1; j < dist.length; j++) {
                if (set.contains(j))
                    continue;
                if (dist[j] <= dist[0]) {
                    dist[0] = dist[j];
                    K = j;
                }
            }
            dist[0] = Integer.MAX_VALUE;
        }
        dist[0] = 0;
        for (int i = 1; i < dist.length; i++) {
            if (dist[i] == Integer.MAX_VALUE)
                return -1;
            else if (dist[i] > dist[0])
                dist[0] = dist[i];
        }
        return dist[0];
    }

参考评论:

    /**
     * Floyd-Warshall 算法
     * 丁大勺
     */
    public int networkDelayTime(int[][] times, int N, int K) {
        /*
        本质上是求单点到所有其他点的最短距离,最后求最短距离中的最大值。
        使用Floyd-Warshall 算法求解。
        */
        K--;  //输入中节点编号是基1,故减1
        int[] dis = new int[N];  //存储K到每个点的最短距离
        for (int i = 0; i < N; i++) {
            dis[i] = Integer.MAX_VALUE;
        }
        dis[K] = 0;
        for (int i = 0; i < N; i++) {
            for (int[] edge : times) {
                //输入中节点编号是基1,故减1
                int u = edge[0] - 1, v = edge[1] - 1, w = edge[2];
                if (dis[u] != Integer.MAX_VALUE && dis[v] > dis[u] + w)
                    dis[v] = dis[u] + w;
            }
        }
        //求最短距离中的最大值
        int res = 0;
        for (int i = 0; i < N; i++) {
            res = Math.max(res, dis[i]);
        }
        return res == Integer.MAX_VALUE ? -1 : res;
    }

结果:

    public int networkDelayTime1(int[][] times, int N, int K) {
        int[] dist = new int[N + 1];
        for (int i = 0; i < dist.length; i++) {
            dist[i] = Integer.MAX_VALUE;
        }
        dist[K] = 0;
        for (int i = 0; i < N; i++) {
            for (int[] edge : times) {
                int u = edge[0], v = edge[1], w = edge[2];
                if (dist[u] != Integer.MAX_VALUE && dist[v] > dist[u] + w)
                    dist[v] = dist[u] + w;
            }
        }
        int res = 0;//dist[0] = 0;
        for (int i = 1; i <= N; i++) {
            if ((res = Math.max(res, dist[i])) == Integer.MAX_VALUE)
                return -1;
        }
        return res;
    }

总结:发现使用数组来存储比使用单个变量来存储更加消耗内存和时间,对Floyd - Warshall算法和Dijkstra算法理解的不够透彻,思维不够程序化,对计算机来说,有时候直接遍历是最快的。

吐槽一下leetcode,明明同样的代码,第一次提交运行38ms,第二次就67ms了,有点迷...

猜你喜欢

转载自www.cnblogs.com/rynar/p/11185468.html