785. 判断二分图——本质上就是图的遍历 dfs或者bfs
785. 判断二分图
给定一个无向图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
我们不能将节点分割成两个独立的子集。
二分图又称作二部图,是图论中的一种特殊模型。 设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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
思路
如果节点属于第一个集合,将其着为蓝色,否则着为红色。只有在二分图的情况下,可以使用贪心思想给图着色:一个节点为蓝色,说明它的所有邻接点为红色,它的邻接点的所有邻接点为蓝色,依此类推。
算法
使用数组(或者哈希表)记录每个节点的颜色: 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
2018-04-11 leetcode 202. Happy Number
2018-04-11 Unbuntu 终端中使用Tab键不能自动补全