1. 题目与解析
在一个有向图中,节点分别标记为
0, 1, ..., n-1。图中每条边为红色或者蓝色,且存在自环或平行边。
red_edges中的每一个[i, j]对表示从节点i到节点j的红色有向边。类似地,blue_edges中的每一个[i, j]对表示从节点i到节点j的蓝色有向边。返回长度为
n的数组answer,其中answer[X]是从节点0到节点X的红色边和蓝色边交替出现的最短路径的长度。如果不存在这样的路径,那么answer[x] = -1。
可以使用广度优先搜索的方法解题。
首先,需要记录两种颜色的单向图的临接表,以供后期的广度优先搜索使用。
使用广度优先搜索获取从节点 0 到某一节点的两种类型的颜色交替最短路径的长度,广度优先搜索的队列元素由节点编号和节点路径类型组成,初始时节点 0 到节点 x 的两种类型的颜色交替最短路径的长度都是 1,将初始值入队。
之后,针对不同类型的队列,分别进行广度优先搜索,并且维护两个记录单元,分别记录通过红色以及蓝色路径到达到节点x所需要的步数,每一次需要更新的时候,都会触发后驱节点的更新过程。
最后取两者的最小值构成我们需要的答案输出。
2. 题解
class Solution {
public int[] shortestAlternatingPaths(int n, int[][] redEdges, int[][] blueEdges) {
Queue<Integer> redQue = new LinkedList<>();
Queue<Integer> blueQue = new LinkedList<>();
int[] redList = new int[n];
int[] blueList = new int[n];
Map<Integer, List<Integer>> redMap = new HashMap<>();
Map<Integer, List<Integer>> blueMap = new HashMap<>();
for (int[] arr: redEdges) {
if (!redMap.containsKey(arr[0])) {
redMap.put(arr[0], new ArrayList<>());
}
redMap.get(arr[0]).add(arr[1]);
}
for (int[] arr: blueEdges) {
if (!blueMap.containsKey(arr[0])) {
blueMap.put(arr[0], new ArrayList<>());
}
blueMap.get(arr[0]).add(arr[1]);
}
Arrays.fill(redList, Integer.MAX_VALUE);
Arrays.fill(blueList, Integer.MAX_VALUE);
if (redMap.containsKey(0)) {
for (int to: redMap.get(0)) {
redQue.add(to);
redList[to] = 1;
}
}
if (blueMap.containsKey(0)) {
for (int to: blueMap.get(0)) {
blueQue.add(to);
blueList[to] = 1;
}
}
while (!redQue.isEmpty() || !blueQue.isEmpty()) {
while (!redQue.isEmpty()) {
int poll = redQue.poll();
if (!blueMap.containsKey(poll)) {
continue;
}
for (int to: blueMap.get(poll)) {
if (blueList[to] > redList[poll] + 1) {
blueQue.add(to);
blueList[to] = redList[poll] + 1;
}
}
}
while (!blueQue.isEmpty()) {
int poll = blueQue.poll();
if (!redMap.containsKey(poll)) {
continue;
}
for (int to: redMap.get(poll)) {
if (redList[to] > blueList[poll] + 1) {
redQue.add(to);
redList[to] = blueList[poll] + 1;
}
}
}
}
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
ans[i] = Math.min(redList[i], blueList[i]);
if (ans[i] == Integer.MAX_VALUE) {
ans[i] = -1;
}
}
ans[0] = 0;
return ans;
}
}