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`.
Examples
Constraints
1 <= k <= n <= 1001 <= times.length <= 6000times[i].length == 31 <= ui, vi <= nui != vi0 <= wi <= 100All the pairs (ui, vi) are unique. (i.e., no multiple edges.)
Dijkstra's Algorithm
Approach
We need to find the shortest path from the source node `k` to all other nodes. The answer is the maximum of these shortest paths. Dijkstra's algorithm uses a priority queue (min-heap) to explore the graph efficiently. We start by pushing `(0, k)` onto the heap. We continually extract the node with the minimum time. If it has not been visited, we mark it visited, update our maximum time, and push all its neighbors onto the heap with the accumulated time. If we visit all `n` nodes, we return the maximum time. Otherwise, if the heap empties and we haven't visited all nodes, some nodes are unreachable, so we return `-1`.
Complexity Analysis
Time complexity is O(E log V) because each edge could be pushed to the heap, and heap operations take O(log V) time (where V is the number of nodes, which bounds the heap size). Space complexity is O(V + E) for the adjacency list and priority queue.
class Solution { public int networkDelayTime(int[][] times, int n, int k) { // Build adjacency list: node -> List of (neighbor, weight) Map<Integer, List<int[]>> adj = new HashMap<>(); for (int i = 1; i <= n; i++) { adj.put(i, new ArrayList<>()); } for (int[] time : times) { adj.get(time[0]).add(new int[]{time[1], time[2]}); } // Min-heap to store (time, node) PriorityQueue<int[]> minHeap = new PriorityQueue<>((a, b) -> a[0] - b[0]); minHeap.offer(new int[]{0, k}); Set<Integer> visited = new HashSet<>(); int maxTime = 0; while (!minHeap.isEmpty()) { int[] curr = minHeap.poll(); int time = curr[0]; int node = curr[1]; if (visited.contains(node)) { continue; } visited.add(node); maxTime = Math.max(maxTime, time); for (int[] edge : adj.get(node)) { int neighbor = edge[0]; int weight = edge[1]; if (!visited.contains(neighbor)) { minHeap.offer(new int[]{time + weight, neighbor}); } } } return visited.size() == n ? maxTime : -1; }}