forked from anishLearnsToCode/leetcode-algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NetworkDelayTime.java
65 lines (56 loc) · 2.32 KB
/
NetworkDelayTime.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// https://leetcode.com/problems/network-delay-time
// Single source shortest path algorithm (Dijkstra's Algorithm)
// T: O(E log(N) for dijkstra + N for searching max val)
// S: O(E + N)
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
public class NetworkDelayTime {
private record Node(int value, long time) { }
public int networkDelayTime(int[][] times, int n, int k) {
final Map<Integer, Map<Integer, Integer>> graph = createDirectedGraphFrom(times);
final long[] minTimeTaken = getMinTimeTakenArray(n, k);
final Queue<Node> queue = new PriorityQueue<Node>(Comparator.comparing(Node::time));
queue.add(new Node(k, 0));
while (!queue.isEmpty()) {
Node node = queue.poll();
if (!graph.containsKey(node.value)) continue;
Map<Integer, Integer> vertexNode = graph.get(node.value);
for (int adjacent : vertexNode.keySet()) {
if (minTimeTaken[node.value - 1] + vertexNode.get(adjacent) < minTimeTaken[adjacent - 1]) {
minTimeTaken[adjacent - 1] = minTimeTaken[node.value - 1] + vertexNode.get(adjacent);
queue.add(new Node(adjacent, minTimeTaken[adjacent - 1]));
}
}
}
return allAreReached(minTimeTaken) ? (int) Arrays.stream(minTimeTaken).max().getAsLong() : -1;
}
private Map<Integer, Map<Integer, Integer>> createDirectedGraphFrom(int[][] times) {
final Map<Integer, Map<Integer, Integer>> graph = new HashMap<>();
for (int[] time : times) {
int start = time[0];
int destination = time[1];
int delay = time[2];
graph.putIfAbsent(start, new HashMap<>());
graph.get(start).put(destination, delay);
}
return graph;
}
private long[] getMinTimeTakenArray(int length, int start) {
long[] array = new long[length];
for (int i = 0 ; i < length ; i++) {
array[i] = Integer.MAX_VALUE;
}
array[start - 1] = 0;
return array;
}
private boolean allAreReached(long[] array) {
for (long val : array) {
if (val == Integer.MAX_VALUE) return false;
}
return true;
}
}