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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

原文地址:https://www.cnblogs.com/bonelee/p/12678692.html

时间: 2024-12-30 01:29:50

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

图的遍历——DFS和BFS模板(一般的图)

关于图的遍历,通常有深度优先搜索(DFS)和广度优先搜索(BFS),本文结合一般的图结构(邻接矩阵和邻接表),给出两种遍历算法的模板 1.深度优先搜索(DFS) #include<iostream> #include<unordered_map> #include<queue> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #

图的遍历 DFS和BFS

深度优先搜索 (Depth First Search, DFS): void DFS ( Vertex V ) { visited[ V ] = true; for ( V 点 的每个邻接点 W ) if ( !visited[ W ] ) DFS( W ); } 若有N 个顶点.E 条边,时间复杂度是 用邻接表存储图,有O(N+E) 用邻接矩阵存储图,有O(N 2 ) 广度优先搜索 (Breadth First Search, BFS) void BFS ( Vertex V ) { visi

图的遍历(DFS、BFS)

理论: 深度优先搜索(Depth_Fisrst Search)遍历类似于树的先根遍历,是树的先根遍历的推广: 广度优先搜索(Breadth_First Search) 遍历类似于树的按层次遍历的过程: java实现 Vertex.java package 图; public class Vertex{ String value; boolean isVisited; Vertex(String value) { this.value=value; this.isVisited=false; }

数据结构--图(上)--图的遍历

图的遍历 两种典型的遍历的方法 深度优先搜索(Depth First Search ,DFS) 广度优先搜索(Breadth First Search ,BFS) 深度优先搜索 深度优先搜索的伪码描述 void DFS(Vertex V){ visited[V] = true; for (V的每个邻接点W) if (!isvisited[W]) DFS(W); } 相当于树的先序遍历DFS是树的先序遍历的推广 若有N个顶点,E条边,DFS的时间复杂度是多少呢?    无法确定! 用邻接表存储图,

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

1. 具体题目 给定一个无向图graph,当这个图为二分图时返回true.如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这个图称为二分图.graph将会以邻接表方式给出,graph[i]表示图中与节点i相连的所有节点.每个节点都是一个在0到graph.length-1之间的整数.这图中没有自环和平行边: graph[i] 中不存在i,并且graph[i]中没有重复的值. 示例 1: 输入: [[1,3], [0,2],

数据结构(15):图 深度优先遍历(DFS)

/*-----------------------------------------------*/ /* 邻接矩阵的DFS */ // 基于 数据结构(14) 中的邻接矩阵的结构 #include <iostream> using namespace std; typedef char VertexType; typedef int EdgeType; const int MAXVEX = 100; const int INFINITY = 65535; typedef struct {

树的遍历与图的遍历

研发时候,不要受原来的术语的影响,其实就是想着原来学过的或者看过的可以解决新遇到的问题,这其实是侥幸心理,忘记原来的术语吧,那只是你创新的源泉. 遍历就是把节点按一定规则构成一个线性序列,不同的规则得到不同顺序的线性序列,仅此而已 . 算法是实际问题工作步骤的抽象,不要一味想算法,想想实际情况怎么做的,然后提取算法,然后优化. 不论怎样,要和具体的数据结构结合在一起. 一.树的遍历 对于树的遍历,有三种,就拿前序遍历来说,得到的序列不论怎么拆分(子串,就是要连续),始 终要是根左右,跟在左右前面

[leetcode]785. Is Graph Bipartite? [bai&#39;pɑrtait] 判断二分图

Given an undirected graph, return true if and only if it is bipartite. Example 1: Input: [[1,3], [0,2], [1,3], [0,2]] Output: true Explanation: The graph looks like this: 0----1 | | | | 3----2 We can divide the vertices into two groups: {0, 2} and {1

活动图本质上就是流程图

活动图(activity diagram,动态图)是阐明了业务用例实现的工作流程.业务工作流程说明了业务为向所服务的业务主角提供其所需的价值而必须完成的工作. 在 UML 中, 活动图本质上就是流程图. 它用于描述系统的活动, 判定点和分支等. 活动图是UML用于对系统的动态行为建模的另一种常用工具,它描述活动的顺序,展现从一个活动到另一个活动的控制流.活动图在本质上是一种流程图. 它是UML中用于对系统动态活动建模的图形,反映系统中一个活动到另一个活动的流程,常常用于描述业务过程和并行处理过程