算法初探LeetCode-网络延迟时间

158 阅读1分钟

LeetCode743. 网络延迟时间

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

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

现在,从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1 。

示例 1:

输入: times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
输出: 2

示例 2:

输入: times = [[1,2,1]], n = 2, k = 1
输出: 1

示例 3:

输入: times = [[1,2,1]], n = 2, k = 2
输出: -1

提示:

  • 1 <= k <= n <= 100
  • 1 <= times.length <= 6000
  • times[i].length == 3
  • 1 <= ui, vi <= n
  • ui != vi
  • 0 <= wi <= 100
  • 所有 (ui, vi) 对都 互不相同(即,不含重复边)

思路分析

题要求计算从网络中的给定结点 k 发出信号到所有结点都收到信号的最短时间。由于给定的网络是有向带权图,因此这道题等价于计算从结点 k 到所有结点的最短路径权重。

当图中有 n 个结点时,Bellman-Ford 算法的做法是对图中的所有边执行 n−1 次遍历,得到从结点 kkk 到每个结点的最短路径权重。

创建数组 receiveTimes 记录从结点 k 到每个结点的最短路径权重,初始时 receiveTimes[k]=0,receiveTimes 中的其余元素都是 ∞。

将遍历到的边的起点、终点和权重分别记为 start、end 和 weight,如果 receiveTimes[start]≠∞且 receiveTimes[end]>receiveTimes[start]+weight,则将 receiveTimes[end] 的值更新为 receiveTimes[start]+weight。

初始时可以确定结点 k 对应的最短路径权重是 0。每一次遍历之后,可以确定图中的一个结点对应的最短路径权重,n−1 次遍历之后即可得到从源结点到每个结点的最短路径权重。

算法代码

public int networkDelayTime(int[][] times, int n, int k) {
    int[] receiveTimes = new int[n + 1];
    Arrays.fill(receiveTimes, Integer.MAX_VALUE);
    receiveTimes[0] = receiveTimes[k] = 0;
    for (int i = 1; i < n; i++) {
        for (int[] edge: times) {
            int start = edge[0], end = edge[1], weight = edge[2];
            if (receiveTimes[start] != Integer.MAX_VALUE && receiveTimes[end] > receiveTimes[start] + weight) {
                receiveTimes[end] = receiveTimes[start] + weight;
            }
        }
    }
    int maxTime = Arrays.stream(receiveTimes).max().getAsInt();
    return maxTime != Integer.MAX_VALUE ? maxTime : -1;
}

结果详情

Snipaste_2023-06-29_17-19-56.png

算法复杂度

  • 空间复杂度:O(n)O(n)
  • 时间复杂度:O(nm)O(n*m)

掘金(JUEJIN)一起进步,一起成长!