785. 判断二分图——本质上就是图的遍历 dfs或者bfs

Posted bonelee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

以上是关于785. 判断二分图——本质上就是图的遍历 dfs或者bfs的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 785. 判断二分图 | Python

leetcode.图.785判断二分图-Java

LeetCode - 785. Is Graph Bipartite?

LeetCode图专题(未完成)

785. 判断二分图

判断二分图的染色法