[LeetCode] 743. Network Delay Time
You are given a network of n
nodes, labeled from 1
to n
. You are also given times
, a list of travel times as directed edges times[i] = (ui, vi, wi)
, where ui
is the source node, vi
is the target node, and wi
is the time it takes for a signal to travel from source to target.
We will send a signal from a given node k
. Return the minimum time it takes for all the n
nodes to receive the signal. If it is impossible for all the n
nodes to receive the signal, return -1
.
Example 1:
Input: times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2 Output: 2
Example 2:
Input: times = [[1,2,1]], n = 2, k = 1 Output: 1
Example 3:
Input: times = [[1,2,1]], n = 2, k = 2 Output: -1
Constraints:
1 <= k <= n <= 100
1 <= times.length <= 6000
times[i].length == 3
1 <= ui, vi <= n
ui != vi
0 <= wi <= 100
- All the pairs
(ui, vi)
are unique. (i.e., no multiple edges.)
网络延迟时间。
有 N 个网络节点,标记为 1 到 N。
给定一个列表 times,表示信号经过有向边的传递时间。 times[i] = (u, v, w),其中 u 是源节点,v 是目标节点, w 是一个信号从源节点传递到目标节点的时间。
现在,我们从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/network-delay-time
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题意是从节点 K 出发,问需要多久才能让所有节点都接收到信号。很显然这是个图论 graph 的题,那么我们首先要做的就是把图建立起来。这里因为 input 里给了三个参数,u,v 和 w,表示的是每条边的起点,终点和权重。所以我这里创建一个 hashmap<u, hashmap<v, weight>>。同时既然是问需要多少时间才能让信号传给所有节点,那么这里我们自然会选择代价最小的结果。这一题也是涉及到了 Dijkstra 的概念,有权图的单源最短路径问题。所以我们应该是需要一个 priority queue 来存放每两个点之间的 weight 的。最后我们需要一个 boolean 数组记录每个节点是否访问过。把图创建好之后,我们把起始点 K 和他的权重 0 放入 pq(因为从 K 点出发到 K 点,是没有花费的)。
当 pq 不为空的时候,我们从 pq 中 poll 一个元素出来,并把它标记为 visited,此时我们还需要用 for loop 遍历这个节点所有的邻居节点 next,并把走到下一个节点 next 的代价累加到当前的代价 curDistance上,再放回 pq 继续循环。停止循环的条件是 pq 为空或者所有节点都遍历完了。此时判断节点是否都遍历到了,若是则返回代价 res;否则返回 -1,说明有节点是怎么样都无法从 K 出发访问到的。
时间 O(E + nlogn)
- 构建图的时候我们需要遍历 times 数组,时间复杂度为 O(E)
- 用优先队列决定先去哪个节点的时候,优先队列排序的复杂度为O(nlogn),其中 n 是节点的数量
- 我们还需在过程中遍历整个 hashmap,时间复杂度为 O(n)
- total = O(E + nlogn)
空间O(E + n)
- hashmap 存储 times 数组和每两点间的权重 - O(E) + (n)
- 优先队列会存储所有结点 - O(n)
- total = O(E + n)
Java实现
1 class Solution { 2 public int networkDelayTime(int[][] times, int n, int k) { 3 HashMap<Integer, HashMap<Integer, Integer>> g = new HashMap<>(); 4 // times中的数组 a, a[0]代表源,a[1]代表目标,a[2]代表权值,单向的 5 for (int[] t : times) { 6 int from = t[0]; 7 int to = t[1]; 8 int cost = t[2]; 9 g.putIfAbsent(from, new HashMap<>()); 10 g.get(from).put(to, cost); 11 } 12 13 // 距离, 目标 14 PriorityQueue<int[]> queue = new PriorityQueue<>((a, b) -> a[0] - b[0]); 15 queue.offer(new int[] { 0, k }); 16 boolean[] visited = new boolean[n + 1]; 17 int res = 0; 18 while (!queue.isEmpty()) { 19 int[] cur = queue.poll(); 20 int curDistance = cur[0]; 21 int nextNode = cur[1]; 22 if (visited[nextNode]) { 23 continue; 24 } 25 visited[nextNode] = true; 26 res = curDistance; 27 n--; 28 if (n == 0) { 29 break; 30 } 31 if (g.containsKey(nextNode)) { 32 for (int next : g.get(nextNode).keySet()) { 33 queue.offer(new int[] { curDistance + g.get(nextNode).get(next), next }); 34 } 35 } 36 } 37 return n == 0 ? res : -1; 38 } 39 }