每日一题——颜色交替的最短路径

92 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情


1129. 颜色交替的最短路径

在一个有向图中,节点分别标记为 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

 

示例 1:

输入: n = 3, red_edges = [[0,1],[1,2]], blue_edges = []
输出: [0,1,-1]

示例 2:

输入: n = 3, red_edges = [[0,1]], blue_edges = [[2,1]]
输出: [0,1,-1]

 

提示:

  • 1 <= n <= 100
  • red_edges.length <= 400
  • blue_edges.length <= 400
  • red_edges[i].length == blue_edges[i].length == 2
  • 0 <= red_edges[i][j], blue_edges[i][j] < n

思路

要求有向图中的最短路径,只需要从起点处开始向后走,第一次走到节点处的距离,即为最短的路径,要找出第一次走到节点的距离,可以使用广度优先搜索BFS。

我们首先需要记录的是,对于一个节点,从红色路径走可以走到哪些节点,从蓝色路径走可以走到哪些节点,我们可以使用一个二维的邻接表来存储节点的邻接节点信息。

还需要注意的是,每次在走到下一步时,我们需要记录此时所走的路径颜色,判断下一步时需要变换路径颜色。若我们已经走过了某个节点,下一次走到该节点时一定不会比已有的路径长度更短,故不需要再次判断。

题解

class Solution {
    public int[] shortestAlternatingPaths(int n, int[][] redEdges, int[][] blueEdges) {
        List<Integer>[][] adj = new List[n][2];
        for(int i = 0; i < n; i++) {
            adj[i][0] = new ArrayList<>();
            adj[i][1] = new ArrayList<>();
        }
        for(int[] edge: redEdges) {
            adj[edge[0]][0].add(edge[1]);
        }
        for(int[] edge: blueEdges) {
            adj[edge[0]][1].add(edge[1]);
        }
        int[][] dist = new int[2][n];
        Arrays.fill(dist[0], Integer.MAX_VALUE);
        Arrays.fill(dist[1], Integer.MAX_VALUE);
        Queue<int[]> queue = new ArrayDeque<>();
        queue.offer(new int[]{1, 0});
        queue.offer(new int[]{0, 0});
        dist[0][0] = 0;
        dist[1][0] = 0;
        while(!queue.isEmpty()) {
            int[] tmp = queue.poll();
            int color = tmp[0];//走过的的颜色
            int idx = tmp[1];
            for(int next: adj[idx][color]) {
                if(dist[1 ^ color][next] != Integer.MAX_VALUE) {
                    continue;
                }
                dist[1 ^ color][next] = dist[color][idx] + 1;
                queue.offer(new int[]{1 ^ color, next});
            }
        }
        int[] ans = new int[n];
        for(int i = 0; i < n; i++) {
            ans[i] = Math.min(dist[0][i], dist[1][i]);
            if(ans[i] == Integer.MAX_VALUE) {
                ans[i] = -1;
            }
        }
        return ans;
    }
}