10k

743. Network Delay Time

Question

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.

Algorithm

This question is a typical shortest path problem. I use Dijkstra algorithm to solve it. We do bfs and maintain a minDistTo, finally we check the max value, if it could not send to all the nodes, the res would be MAX_VALUE, otherwise, the max value is the min value or latency required to send signal to all the nodes.

Code2 is the standard answer, which optimize the time by maintain an adjacency list.

Code

class Solution {
    public int networkDelayTime(int[][] times, int n, int k) {
        int[] minDistTo = new int[n + 1];
        boolean[] visited = new boolean[n + 1];
        Arrays.fill(minDistTo, Integer.MAX_VALUE);
        PriorityQueue<Pair<Integer, Integer>> pq = new PriorityQueue<>((a, b) -> (a.getValue() - b.getValue()));
        
        minDistTo[k] = 0;
        pq.offer(new Pair(k, minDistTo[1]));
        
        while (!pq.isEmpty()) {
            Pair<Integer, Integer> pair = pq.poll();
            visited[pair.getKey()] = true;
            int curNode = pair.getKey();
            for (int[] time : times) {
                int start = time[0];
                int end = time[1];
                int latency = time[2];
                if (start == curNode && !visited[end]) {
                    int curDist = minDistTo[start] + latency;
                    if (curDist < minDistTo[end]) {
                        minDistTo[end] = curDist;
                        pq.offer(new Pair(end, curDist));
                    }
                }
            }
        }
        
        int res = Integer.MIN_VALUE;
        for (int i = 1; i < minDistTo.length; i++) {
            res = Math.max(minDistTo[i], res);
        }
        return res != Integer.MAX_VALUE ? res : -1;
        
    }
}

Code2

class Solution {
    // Adjacency list
    Map<Integer, List<Pair<Integer, Integer>>> adj = new HashMap<>();
    
    private void dijkstra(int[] signalReceivedAt, int source, int n) {
        Queue<Pair<Integer, Integer>> pq = new PriorityQueue<Pair<Integer,Integer>>
            (Comparator.comparing(Pair::getKey));
        pq.add(new Pair(0, source));
        
        // Time for starting node is 0
        signalReceivedAt[source] = 0;
        
        while (!pq.isEmpty()) {
            Pair<Integer, Integer> topPair = pq.remove();
            
            int currNode = topPair.getValue();
            int currNodeTime = topPair.getKey();
            
            if (currNodeTime > signalReceivedAt[currNode]) {
                continue;
            }
            
            if (!adj.containsKey(currNode)) {
                continue;
            }
            
            // Broadcast the signal to adjacent nodes
            for (Pair<Integer, Integer> edge : adj.get(currNode)) {
                int time = edge.getKey();
                int neighborNode = edge.getValue();
                
                // Fastest signal time for neighborNode so far
                // signalReceivedAt[currNode] + time : 
                // time when signal reaches neighborNode
                if (signalReceivedAt[neighborNode] > currNodeTime + time) {
                    signalReceivedAt[neighborNode] = currNodeTime + time;
                    pq.add(new Pair(signalReceivedAt[neighborNode], neighborNode));
                }
            }
        }
    }
    
    public int networkDelayTime(int[][] times, int n, int k) {
        // Build the adjacency list
        for (int[] time : times) {
            int source = time[0];
            int dest = time[1];
            int travelTime = time[2];
            
            adj.putIfAbsent(source, new ArrayList<>());
            adj.get(source).add(new Pair(travelTime, dest));
        }
        
        int[] signalReceivedAt = new int[n + 1];
        Arrays.fill(signalReceivedAt, Integer.MAX_VALUE);
        
        dijkstra(signalReceivedAt, k, n);
        
        int answer = Integer.MIN_VALUE;
        for (int i = 1; i <= n; i++) {
            answer = Math.max(answer, signalReceivedAt[i]);
        }
        
        // INT_MAX signifies atleat one node is unreachable
        return answer == Integer.MAX_VALUE ? -1 : answer;
    }
}
Thoughts? Leave a comment