leetcode 1129. 颜色交替的最短路径【BSF方法图解-python3实现过程详解】

文章介绍了如何使用广度优先搜索解决有向图中红色边和蓝色边交替出现的最短路径问题。通过构建图,以源节点0开始进行BFS,同时考虑边的颜色,最终得出每个节点到0的交替路径最短长度。时间复杂度和空间复杂度均与节点数、红色边和蓝色边的数量有关。
摘要由CSDN通过智能技术生成

题目

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

示例

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

题解

这个题目其实方法很容易确定,由于有颜色的交替,因此想到广度优先是很自然的事情。一图胜前言,还是用图说话比较清晰。
image.png
上图是一个广度优先遍历的过程,过程比较简单,从初始节点0开始根据交替变幻边的颜色来实现广度优先遍历。下面我们如何实践这个过程来得到最终结果呢?
首先面临的一个问题就是边的表示问题,这里边包含的信息量较多,有源节点,目的节点与颜色。直接用三元组表示不是特别方便,这里城根据源节点找到这些边,hash表是个不错的选择,但这里可更简化一下把源节点作为列表的索引,就剩下目的节点与颜色二元组了。
image.png
比如上图中的节点0到1的边可以表示成下面的列表形式,源节点0对应列表中的第0个元素,该元素中的第1个值表示目标节点,第二个值表示边的颜色。
到这里基本上就可以写代码了,代码整理如下:

class Solution:
    def shortestAlternatingPaths(self, n: int, redEdges: List[List[int]], blueEdges: List[List[int]]) -> List[int]:
        #构建图,图列表的索引表示
        g=[[] for _ in range(n)]
        for s,t in redEdges:
            g[s].append((t,0))
        for s,t in blueEdges:
            g[s].append((t,1))

        dis=[-1]*n
        #已遍历过的,由0到0开始,0到0的颜色两种均可加上不会对结构有影响
        vis={(0,0),(0,1)}
        #广度优先第一层节点初始化
        q=[(0,0),(0,1)]
        level=0
        while q:
            next_q=[]
            for x,color in q:
                if dis[x]==-1:
                    dis[x]=level
                #遍历q中的x节点的下一跳
                for p in g[x]:
                    if p[1]!=color and p not in vis:
                        vis.add(p)
                        next_q.append(p)
            q=next_q
            level+=1
        return dis

计算复杂

  • 时间复杂度: O ( n + r + b ) O(n+r+b) O(n+r+b),其中 n n n 是节点数,r 是红色边的数目,b是蓝色边的数目。广度优先搜索最多访问一个节点两次,最多访问一条边一次,因此时间复杂度为 O ( n + r + b ) O(n+r+b) O(n+r+b)
  • 空间复杂度: O ( n + r + b ) O(n+r+b) O(n+r+b)。队列中最多有 2n个元素,保存 next 需要 O ( n + r + b ) O(n+r+b) O(n+r+b)的空间,保存 dist需要 O ( n ) O(n) O(n) 的空间。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值