forked from ex01tus/leetcode-grind
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathShortestPathWithAlternatingColors.java
More file actions
74 lines (58 loc) · 2.44 KB
/
ShortestPathWithAlternatingColors.java
File metadata and controls
74 lines (58 loc) · 2.44 KB
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
66
67
68
69
70
71
72
73
74
package graph;
import java.util.*;
/**
* Description: https://leetcode.com/problems/shortest-path-with-alternating-colors
* Difficulty: Medium
* Time complexity: O(n)
* Space complexity: O(n)
*/
public class ShortestPathWithAlternatingColors {
private static final int RED = 0;
private static final int BLUE = 1;
private static final int UNKNOWN = -1;
public int[] shortestAlternatingPaths(int n, int[][] redEdges, int[][] blueEdges) {
Map<Integer, List<Node>> adjList = toAdjList(redEdges, blueEdges);
return findShortestPaths(adjList, n);
}
private int[] findShortestPaths(Map<Integer, List<Node>> adjList, int n) {
int[] distances = new int[n];
Arrays.fill(distances, -1);
distances[0] = 0;
int[][] visited = new int[n][2]; // each node can be visited twice: via red edge and via blue edge
visited[0][RED] = 1;
visited[0][BLUE] = 1;
Queue<Node> planned = new LinkedList<>();
planned.offer(new Node(0, UNKNOWN)); // can start our path with both red and blue edges
int distance = 0;
while (!planned.isEmpty()) {
int levelSize = planned.size();
distance++;
for (int i = 0; i < levelSize; i++) {
Node current = planned.poll();
for (Node neighbor : adjList.getOrDefault(current.idx, List.of())) {
if (visited[neighbor.idx][neighbor.edgeColor] == 0
&& neighbor.edgeColor != current.edgeColor) { // alternate edge colors
if (distances[neighbor.idx] == -1) { // only update distance once
distances[neighbor.idx] = distance;
}
visited[neighbor.idx][neighbor.edgeColor] = 1;
planned.offer(neighbor);
}
}
}
}
return distances;
}
private Map<Integer, List<Node>> toAdjList(int[][] redEdges, int[][] blueEdges) {
Map<Integer, List<Node>> adjList = new HashMap<>();
for (int[] edge : redEdges) {
adjList.computeIfAbsent(edge[0], __ -> new ArrayList<>()).add(new Node(edge[1], RED));
}
for (int[] edge : blueEdges) {
adjList.computeIfAbsent(edge[0], __ -> new ArrayList<>()).add(new Node(edge[1], BLUE));
}
return adjList;
}
private record Node(int idx, int edgeColor) {
}
}