zoukankan      html  css  js  c++  java
  • 785. 判断二分图——本质上就是图的遍历 dfs或者bfs

    785. 判断二分图

    给定一个无向图graph,当这个图为二分图时返回true

    如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这个图称为二分图。

    graph将会以邻接表方式给出,graph[i]表示图中与节点i相连的所有节点。每个节点都是一个在0graph.length-1之间的整数。这图中没有自环和平行边: graph[i] 中不存在i,并且graph[i]中没有重复的值。

    
    示例 1:
    输入: [[1,3], [0,2], [1,3], [0,2]]
    输出: true
    解释: 
    无向图如下:
    0----1
    |    |
    |    |
    3----2
    我们可以将节点分成两组: {0, 2} 和 {1, 3}。
    
    
    示例 2:
    输入: [[1,2,3], [0,2], [0,1,3], [0,2]]
    输出: false
    解释: 
    无向图如下:
    0----1
    |   |
    |   |
    3----2
    我们不能将节点分割成两个独立的子集。
    

    二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。
    简而言之,就是顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集,两个子集内的顶点不相邻。
    区别二分图,关键是看点集是否能分成两个独立的点集。
    上图中U和V构造的点集所形成的循环圈不为奇数,所以是二分图。
    上图中U和V和W构造的点集所形成的的循环圈为奇数,所以不是二分图。
     
    方法一:深度优先搜索着色【通过】

    思路

    如果节点属于第一个集合,将其着为蓝色,否则着为红色。只有在二分图的情况下,可以使用贪心思想给图着色:一个节点为蓝色,说明它的所有邻接点为红色,它的邻接点的所有邻接点为蓝色,依此类推。

    算法

    使用数组(或者哈希表)记录每个节点的颜色: color[node]。颜色可以是 0, 1,或者未着色(-1 或者 null)。

    搜索节点时,需要考虑图是非连通的情况。对每个未着色节点,从该节点开始深度优先搜索着色。每个邻接点都可以通过当前节点着相反的颜色。如果存在当前点和邻接点颜色相同,则着色失败。

    使用栈完成深度优先搜索,栈类似于节点的 “todo list”,存储着下一个要访问节点的顺序。在 graph[node] 中,对每个未着色邻接点,着色该节点并将其放入到栈中。

    class Solution(object):
        def isBipartite(self, graph):
            color = {}
            for node in xrange(len(graph)):
                if node not in color:
                    stack = [node]
                    color[node] = 0
                    while stack:
                        node = stack.pop()
                        for nei in graph[node]:
                            if nei not in color:
                                stack.append(nei)
                                color[nei] = color[node] ^ 1
                            elif color[nei] == color[node]:
                                return False
            return True

    复杂度分析

        时间复杂度:O(N+E)O(N + E)O(N+E),其中 NNN 是节点的数量,EEE 是边的数量。着色每个节点时,遍历其所有边。

        空间复杂度:O(N)O(N)O(N),存储 color 的栈。

    作者:LeetCode
    链接:https://leetcode-cn.com/problems/is-graph-bipartite/solution/pan-duan-er-fen-tu-by-leetcode/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    小端大端
    位域
    c++ 2.1 编译器何时创建默认构造函数
    python 内置&&递归
    python返回值与局部全局变量
    python file
    python set
    python 字典的函数
    python FileError
    python pickle
  • 原文地址:https://www.cnblogs.com/bonelee/p/12678692.html
Copyright © 2011-2022 走看看