middle-判断二分图-深度优先和广度优先

在这里插入图片描述
在这里插入图片描述
二分图,所以每一条边的两个节点不能是一样的。记住上一个节点就可以解决下一个节点。

下面的运行要注意一些是孤立部分,不一定是一整个完全连接的图像,所以要对每一个节点判断一下是否已经访问过了。

1.深度优先遍历

递归解决
先从0开始,依次往下深度遍历。直到最后一个节点,依次返回。
队列每进一个点就将其上色,通过判断颜色的不同来判断是不是二分图。

def isBipartite(self, graph: List[List[int]]) -> bool:
    def dfs(node, color):
        for i in graph[node]:
            if i not in color_dict:
                color_dict[i] = 0 if color else 1
                sign = dfs(i, color_dict[i])
                if not sign:    
                    return False
            else:
                if color_dict[i] == color:
                    return False
        return True


    color_dict = {}

    for i, info in enumerate(graph):
        if i not in color_dict:
            color_dict[i] = 0
            if dfs(i, color_dict[i]):
                continue
            else:
                return False
        else:
            continue
    
    return True

2.广度优先遍历

从0开始,先把0的邻居都访问一遍,依次进队列。广度优先遍历通过队列实现。

from collections import deque
class Solution(object):
    def isBipartite(self, graph):
        """
        :type graph: List[List[int]]
        :rtype: bool
        广度优先搜索,用队列解决。因为先进先出,通过队列来保存前面的值,便于继续下一层
        时间复杂度O(m+n)点数加上边数;
        邻接表表示时,查找所有顶点的邻接点所需时间为O(E),访问顶点的邻接点所花时间为O(V),此时,总的时间复杂度为O(V+E)
        """
        queue = deque()
        color_dict = {}
        queue.append(0)
        color_dict[0] = 0
        for i in range(len(graph)):
            while len(queue) > 0:
                head = queue.popleft()  
                for graphi in graph[head]:
                    if graphi not in color_dict:
                        queue.append(graphi)
                        if color_dict[head]:
                            color_dict[graphi] = 0
                        else:
                            color_dict[graphi] = 1
                    else:
                        if color_dict[graphi] == color_dict[head]:
                            return False

            if i not in color_dict: # 孤立点
                queue.append(i)
                color_dict[i] = 0

        return True
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值