二分图,所以每一条边的两个节点不能是一样的。记住上一个节点就可以解决下一个节点。
下面的运行要注意一些是孤立部分,不一定是一整个完全连接的图像,所以要对每一个节点判断一下是否已经访问过了。
1.深度优先遍历
递归解决
先从0开始,依次往下深度遍历。直到最后一个节点,依次返回。
队列每进一个点就将其上色,通过判断颜色的不同来判断是不是二分图。
def isBipartite(self, graph: List[List[int]]) -> bool:
def dfs(node, color):
for i in graph[node]:
if i not in color_dict:
color_dict[i] = 0 if color else 1
sign = dfs(i, color_dict[i])
if not sign:
return False
else:
if color_dict[i] == color:
return False
return True
color_dict = {}
for i, info in enumerate(graph):
if i not in color_dict:
color_dict[i] = 0
if dfs(i, color_dict[i]):
continue
else:
return False
else:
continue
return True
2.广度优先遍历
从0开始,先把0的邻居都访问一遍,依次进队列。广度优先遍历通过队列实现。
from collections import deque
class Solution(object):
def isBipartite(self, graph):
"""
:type graph: List[List[int]]
:rtype: bool
广度优先搜索,用队列解决。因为先进先出,通过队列来保存前面的值,便于继续下一层
时间复杂度O(m+n)点数加上边数;
邻接表表示时,查找所有顶点的邻接点所需时间为O(E),访问顶点的邻接点所花时间为O(V),此时,总的时间复杂度为O(V+E)
"""
queue = deque()
color_dict = {}
queue.append(0)
color_dict[0] = 0
for i in range(len(graph)):
while len(queue) > 0:
head = queue.popleft()
for graphi in graph[head]:
if graphi not in color_dict:
queue.append(graphi)
if color_dict[head]:
color_dict[graphi] = 0
else:
color_dict[graphi] = 1
else:
if color_dict[graphi] == color_dict[head]:
return False
if i not in color_dict: # 孤立点
queue.append(i)
color_dict[i] = 0
return True