题目:网络延迟时间
有 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 <= 1001 <= times.length <= 6000times[i].length == 31 <= ui, vi <= nui != vi0 <= wi <= 100- 所有
(ui, vi)对都 互不相同(即,不含重复边)
解题思路
题目以又向边的方式给出我们每一条边,然后我们可以根据这个来构建出一个有向图 其实这个题目就是一个求最短路径的题目,从 k 点出发到达每一个可以到达的点
每一层的处理如下: 1、记录下一层距离最近的节点的距离。 2、非当前层的最近节点,把节点的距离更新后,排到下一层。 3、若是当前层的最近节点,则把该节点的子节点全部加到队列。
使用迪杰斯特拉的最短路径算法
- 先构建图的邻接矩阵,使用权重填充有向边对应的元素
- 使用最小堆,小根堆中的元素为{起点出发到当前节点的距离,当前节点的标号},以有向边的权值进行比较
- 每次选择最小边,且没到遍历过的节点进行操作,将相邻的节点入队
- 直到所有节点都遍历完一次为止,如果不能遍历完所有的节点则返回-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;
}
运行结果
复杂度分析
- 空间复杂度:O(1)
- 时间复杂度:O(n)
在掘金(JUEJIN) 一起分享知识, Keep Learning!