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。
示例 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]
示例 3:
输入:n = 3, red_edges = [[1,0]], blue_edges = [[2,1]]
输出:[0,-1,-1]
示例 4:
输入:n = 3, red_edges = [[0,1]], blue_edges = [[1,2]]
输出:[0,1,2]
示例 5:
输入:n = 3, red_edges = [[0,1],[0,2]], blue_edges = [[1,0]]
输出:[0,1,1]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-path-with-alternating-colors
2. 思路分析:
① 这道题目有一个比较明显的特点是需要尝试才能够知道最终的答案,并且还是一个图论的问题所以可以使用dfs搜索来解决,但是怎么样去处理搜索的细节是一个需要思考的问题,因为是红蓝交替出现的所以感觉处理起来还是需要一定的技巧的,在领扣的题解中发现一个比较好的处理搜索细节的方法,使用的是c++代码编写的,我自己理解之后使用了python语言进行解决,下面是我对于大佬的代码的一些理解
② 比较核心的是使用一个二维列表记录中间的结果,第一维表示的是当前的顶点,第二维表示的是颜色,0表示红色,1表示蓝色,在递归的过程中需要交替递归不同颜色的路径这样才可以表示红蓝交替出现的路径,所以可以使用一个三维的列表来表示题目中给出的红色路径与蓝色路径表示的图,我们在递归的时候可以传入当前递归的颜色,往下递归的时候就可以根据传入的颜色来决定往下递归的是哪一种颜色的路径,在递归的dfs方法中比较核心的是下面的if判断:
这个可以自己在图上画一下具体的例子来理解会更好一点
③ 在dfs搜索的过程中,需要使用下标也就是当前的顶点来进行递归的,这里可以使用collections.defaultdict(list)创建字典的形式来存储图,这样在递归的时候可以直接使用下标进行访问
3. 代码如下:
import collections
import sys
from typing import List
class Solution:
def dfs(self, graph: List[List[List[int]]], color: int, res: List[List[int]], cur: int):
# 可以使用异或操作来表示0还是1
for i in graph[color][cur]:
if res[cur][color] + 1 < res[i][color ^ 1]:
res[i][color ^ 1] = res[cur][color] + 1
self.dfs(graph, color ^ 1, res, i)
def shortestAlternatingPaths(self, n: int, red_edges: List[List[int]], blue_edges: List[List[int]]) -> List[int]:
# 初始化能够使用下标来访问的红色和蓝色的有向图
rg, bg = collections.defaultdict(list), collections.defaultdict(list)
for cur in red_edges:
rg[cur[0]].append(cur[1])
for cur in blue_edges:
bg[cur[0]].append(cur[1])
graph = list()
graph.append(rg)
graph.append(bg)
res = [[sys.maxsize] * 2 for i in range(n)]
res[0][0], res[0][1] = 0, 0
self.dfs(graph, 0, res, 0)
self.dfs(graph, 1, res, 0)
ans = [0 for i in range(n)]
for i in range(n):
ans[i] = min(res[i][0], res[i][1])
if ans[i] == sys.maxsize:
ans[i] = -1
return ans