夯实算法-网络延迟时间

146 阅读1分钟

题目:网络延迟时间

有 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 点出发到达每一个可以到达的点

每一层的处理如下: 1、记录下一层距离最近的节点的距离。 2、非当前层的最近节点,把节点的距离更新后,排到下一层。 3、若是当前层的最近节点,则把该节点的子节点全部加到队列。

使用迪杰斯特拉的最短路径算法

  1. 先构建图的邻接矩阵,使用权重填充有向边对应的元素
  2. 使用最小堆,小根堆中的元素为{起点出发到当前节点的距离,当前节点的标号},以有向边的权值进行比较
  3. 每次选择最小边,且没到遍历过的节点进行操作,将相邻的节点入队
  4. 直到所有节点都遍历完一次为止,如果不能遍历完所有的节点则返回-1

代码实现

public int networkDelayTime(int[][] times, int n, int k) {

    int[][] g = new int[n + 1][n + 1];
    int[] dist = new int[n + 1];
    Arrays.fill(dist, -1);
    for (int i = 0; i <= n; i++)
        Arrays.fill(g[i], -1);
    for (int[] time: times)
        g[time[0]][time[1]] = time[2];
    PriorityQueue < int[] > pq = new PriorityQueue < > ((o1, o2) - > o1[0] - o2[0]);
    pq.add(new int[] {
        0, k
    });
    while (!pq.isEmpty()) {
        int[] cur = pq.poll();
        if (dist[cur[1]] != -1) continue;
        dist[cur[1]] = cur[0];
        for (int i = 1; i <= n; i++)
            if (g[cur[1]][i] != -1) {
                pq.add(new int[] {
                    cur[0] + g[cur[1]][i], i
                });
            }
    }
    int cnt = 0, max = 0;
    for (int i = 1; i <= n; i++) {
        if (dist[i] == -1)
            return -1;
        max = Math.max(max, dist[i]);
    }
    return max;

}

运行结果

zby1.png

复杂度分析

  • 空间复杂度:O(1)
  • 时间复杂度:O(n)

掘金(JUEJIN) 一起分享知识, Keep Learning!