Title

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

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

graph将会以邻接表方式给出,graph[i]表示图中与节点i相连的所有节点。每个节点都是一个在0到graph.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

我们不能将节点分割成两个独立的子集。

注意:

  • graph 的长度范围为 [1, 100]。
  • graph[i] 中的元素的范围为 [0, graph.length - 1]。
  • graph[i] 不会包含 i 或者有重复的值。
  • 图是无向的: 如果j 在 graph[i]里边, 那么 i 也会在 graph[j]里边。

Solve

对于图中的任意两个节点 u 和 v,如果它们之间有一条边直接相连,那么 u 和 v 必须属于不同的集合。

如果给定的无向图连通,那么我们就可以任选一个节点开始,给它染成红色。随后我们对整个图进行遍历,将该节点直接相连的所有节点染成绿色,表示这些节点不能与起始节点属于同一个集合。我们再将这些绿色节点直接相连的所有节点染成红色,以此类推,直到无向图中的每个节点均被染色。

如果我们能够成功染色,那么红色和绿色的节点各属于一个集合,这个无向图就是一个二分图;如果我们未能成功染色,即在染色的过程中,某一时刻访问到了一个已经染色的节点,并且它的颜色与我们将要给它染上的颜色不相同,也就说明这个无向图不是一个二分图。

算法的流程如下:

  • 我们任选一个节点开始,将其染成红色,并从该节点开始对整个无向图进行遍历;
  • 在遍历的过程中,如果我们通过节点 u 遍历到了节点 v(即 u 和 v 在图中有一条边直接相连),那么会有两种情况:
    • 如果 v 未被染色,那么我们将其染成与 u 不同的颜色,并对 v 直接相连的节点进行遍历;
    • 如果 v 被染色,并且颜色与 u 相同,那么说明给定的无向图不是二分图。我们可以直接退出遍历并返回 False 作为答案。
  • 当遍历结束时,说明给定的无向图是二分图,返回 True 作为答案。

注意:题目中给定的无向图不一定保证连通,因此我们需要进行多次遍历,直到每一个节点都被染色,或确定答案为 False 为止。每次遍历开始时,我们任选一个未被染色的节点,将所有与该节点直接或间接相连的节点进行染色。

深度优先搜索

Code

 def isBipartite_DFS(self, graph: List[List[int]]) -> bool:n, unColored, red, green = len(graph), 0, 1, 2color, valid = [unColored] * n, Truedef dfs(node: int, c: int):nonlocal validcolor[node] = cnextC = (green if c == red else red)for neighbor in graph[node]:if color[neighbor] == unColored:dfs(neighbor, nextC)if not valid:returnelif color[neighbor] != nextC:valid = Falsereturnfor i in range(n):if color[i] == unColored:dfs(i, red)if not valid:breakreturn valid

复杂度分析

时间复杂度:O(N+M),其中 N 和 M 分别是无向图中的点数和边数。

空间复杂度:O(N),存储节点颜色的数组需要 O(N) 的空间,并且在深度优先搜索的过程中,栈的深度最大为 N,需要 O(N) 的空间。

广度优先搜索

Code

 def isBipartite_BFS(self, graph: List[List[int]]) -> bool:n, unColored, red, green = len(graph), 0, 1, 2color = [unColored] * nfor i in range(n):if color[i] == unColored:q = collections.deque([i])color[i] = redwhile q:node = q.popleft()nextC = (green if color[node] == red else red)for neighbor in graph[node]:if color[neighbor] == unColored:q.append(neighbor)color[neighbor] = nextCelif color[neighbor] != nextC:return Falsereturn True

复杂度分析

时间复杂度:O(N+M),其中 N 和 M 分别是无向图中的点数和边数。

空间复杂度:O(N),存储节点颜色的数组需要 O(N) 的空间,并且在广度优先搜索的过程中,队列中最多有 N-1 个节点,需要 O(N) 的空间。

785. Is Graph Bipartite? 判断二分图相关推荐

  1. leetcode 785. Is Graph Bipartite? | 785. 判断二分图(DFS,地图着色)

    题目 https://leetcode.com/problems/is-graph-bipartite/ 题解 有点像简化版的地图着色问题. 每走一步,颜色翻转一下,并且染色. 当遇到已经染过色的节点 ...

  2. LeetCode - 785. Is Graph Bipartite?

    判断一个给定图是不是二分图. 题目提供一个用二维数组存储的邻接表. 常规的二分图判断,点着色. 注意要将图存入类中,因为dfs需要访问图中的点. 1 class Solution { 2 privat ...

  3. 【Breadth-first Search 】785. Is Graph Bipartite?

    输入:一个无向图graph.graph[i] 的值是一些节点,表示从i到这些节点有边.图中节点用0到graph.length-1表示.这个图没有指向自己的边,也就是说节点i不会有指向节点i的边.输入中 ...

  4. 判断二分图【bfs】

    题目是判断二分图 给定一个可能不是连通的无向图,我们需要判断此图是不是一个二分图. 在一个连通的无向图内,判断二分图的方法为: 初始化所有结点都未染色,染色数组color初始化全未0 从任意一个结点开 ...

  5. CodeForces - 1354E Graph Coloring(dfs判断二分图+dp)

    题目链接:点击查看 题目大意:给出一个由 n 个点和 m 条边组成的无向图,要求给 n 个点赋值为 1 . 2 或 3 ,需要满足以下条件: 每个点都需要被赋值 权值为 1 的点共 n1 个 权值为 ...

  6. LeetCode 785. 判断二分图(染色法)

    文章目录 1. 题目 2. 解题 1. 题目 给定一个无向图graph,当这个图为二分图时返回true. 如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A ...

  7. [Leetcode][第785题][JAVA][判断二分图][BFS][DFS]

    [问题描述][中等] [解答思路] 1. DFS 深度优先遍历 时间复杂度:O(N+M) 空间复杂度:O(N) class Solution {private static final int UNC ...

  8. 图论 —— 染色法判断二分图

    二分图定义 二分图,又称二部图,英文名叫 Bipartite graph. 二分图是什么?节点由两个集合组成,且两个集合内部没有边的图.换言之,存在一种方案,将节点划分成满足以上性质的两个集合. 二分 ...

  9. LeetCode_二分图_中等_785. 判断二分图

    目录 1.题目 2.思路 3.代码实现(Java) 1.题目 存在一个无向图,图中有 n 个节点.其中每个节点都有一个介于 0 到 n - 1 之间的唯一编号.给你一个二维数组 graph,其中 gr ...

最新文章

  1. 对软件工程与计算机科学之间区别的看法
  2. Synchronize对象改变
  3. 如何下载多段ts视频 m3u8 ffmpeg
  4. Python字符串函数说明(菜鸟教程里面的)
  5. 在VMware安装Windows server 2003步骤
  6. 全国计算机三级数据库技术
  7. 如何在屏幕实时显示键盘操作(独家分享)
  8. echarts自定义地图
  9. 大灾变黑暗日子:静态分析和Roguelike游戏
  10. MTK OTA更新方法
  11. JavaScript学习笔记[红皮书]
  12. 打印机一直不停打乱码的解决方法
  13. 漏洞复现 - - - Springboot未授权访问
  14. Android 解决OutOfMemory,从避免内存溢出开始
  15. debug模式启用浏览器
  16. 解析grant connect, resource to user语句
  17. centos(7.9) minikube(v1.28.0) kaniko 构建镜像
  18. php中标识符不正确的是,下面PHP标识符中定义不正确的是( )
  19. 情感分类——Attention(前篇)
  20. mysql mdl 锁_mysql原理 ~ 细说 MDL锁

热门文章

  1. jQuery相关方法6----三大系列属性
  2. js 前加分号和感叹号的含义
  3. DIV+CSS两种盒子模型(W3C盒子与IE盒子)
  4. tomcat高并发配置
  5. Python 一路走来 Django
  6. 《Android群英传》读书笔记 (5) 第十一章 搭建云端服务器 + 第十二章 Android 5.X新特性详解 + 第十三章 Android实例提高...
  7. 解读Android LOG机制的实现
  8. [MSDN]每个开发人员现在应该下载的十种必备工具
  9. ubuntu18.04安装QQ-for-Linux
  10. 实验4-2-3 pta验证“哥德巴赫猜想” (20分)