网络延迟时间
难度:
标签:
题目描述
有 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)
对都 互不相同(即,不含重复边)
代码结果
运行时间: 45 ms, 内存: 17.7 MB
/*
* Problem: Given a list of travel times between directed edges in a network, determine how long it will take for all nodes to receive a signal sent from a starting node K. If not all nodes can receive the signal, return -1.
* Approach: Use Java Streams to process the input and apply Dijkstra's algorithm. The result will be the maximum time required for the signal to reach all nodes or -1 if not all nodes can be reached.
*/
import java.util.*;
import java.util.stream.Collectors;
public class NetworkDelayTimeStream {
public int networkDelayTime(int[][] times, int n, int k) {
// Create an adjacency list
Map<Integer, List<int[]>> graph = Arrays.stream(times)
.collect(Collectors.groupingBy(
time -> time[0],
Collectors.mapping(time -> new int[]{time[1], time[2]}, Collectors.toList())
));
// PriorityQueue to get the minimum distance node
PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparingInt(a -> a[1]));
pq.offer(new int[]{k, 0});
Map<Integer, Integer> dist = new HashMap<>();
dist.put(k, 0);
// Dijkstra's algorithm
while (!pq.isEmpty()) {
int[] info = pq.poll();
int node = info[0], time = info[1];
if (time > dist.get(node)) continue;
if (!graph.containsKey(node)) continue;
for (int[] edge : graph.get(node)) {
int neighbor = edge[0], d = time + edge[1];
if (d < dist.getOrDefault(neighbor, Integer.MAX_VALUE)) {
dist.put(neighbor, d);
pq.offer(new int[]{neighbor, d});
}
}
}
// Find the maximum distance
if (dist.size() != n) return -1;
return dist.values().stream().max(Integer::compareTo).orElse(-1);
}
}
解释
方法:
这个解决方案使用邻接矩阵来表示图,并通过一个修改版的迪杰斯特拉算法来找到从节点K到所有其他节点的最短路径。算法开始时,初始化一个距离数组,所有节点的距离设为无穷大,除了起点K,其距离设为0。然后使用一个布尔数组来跟踪每个节点的访问状态。对于每一次循环,选择一个未访问的且距离最小的节点作为当前节点,然后遍历其所有邻居,更新邻居的最短距离。这一过程重复n次,每次处理一个节点。最后,从距离数组中找出最大值,如果所有节点都已访问(即最大值不是无穷大),则返回此最大值作为结果,否则返回-1。
时间复杂度:
O(n^2)
空间复杂度:
O(n^2)
代码细节讲解
🦆
为什么在这个算法中选择使用邻接矩阵而不是邻接列表来表示图?
▷🦆
在迪杰斯特拉算法中,如何确定当前节点的所有邻居节点,特别是在使用邻接矩阵表示图的情况下?
▷🦆
算法中如何处理图中的环或者自环(即从一个节点指向自身的边)?
▷🦆
在找到距离最小的未访问节点时,该算法是否考虑了效率优化,例如使用优先队列来优化查找过程?
▷