题目描述
解析
用一个字典表示分组情况,一组value为True,另一组为False
- 若已经为True的组 也应该为False (奇数个节点组成的环)则返回 False
- 孤立节点 可以属于任意一组,故可以忽略
- 图可能非连通,即存在多个连通子图,代码里是用
for
循环遍历的下标,即遍历多个连通子图(若存在)
- BFS
import collections
from typing import List
class Solution:
def isBipartite(self, graph: List[List[int]]) -> bool:
data = {}
queue = collections.deque()
for i in range(len(graph)):
if graph[i] and i not in data: # 度不为0的节点,且未出现过(另一个连通子图)
queue.clear()
queue.append((i, True))
while queue:
top = queue.popleft()
if top[0] in data and data[top[0]] != top[1]:
return False
elif top[0] not in data:
data[top[0]] = top[1]
key = not top[1]
for one in graph[top[0]]:
queue.append((one, key))
return True
- DFS
import collections
from typing import List
class Solution:
def isBipartite(self, graph: List[List[int]]) -> bool:
data = {}
def dfs(index, key):
res = True
if index in data and data[index] != key: return False
elif index not in data:
data[index] = key
key = not key
for one in graph[index]:
res = res and dfs(one, key)
return res
result = True
for i in range(len(graph)):
if graph[i] and i not in data:
result = result and dfs(i, True)
if not result: return False
return True
-
时间复杂度: O ( N + M ) O(N+M) O(N+M),其中 N N N 和 M M M 分别是无向图中的点数和边数。
-
空间复杂度: O ( N ) O(N) O(N),存储节点颜色的数组需要 O ( N ) O(N) O(N) 的空间,并且在广度优先搜索的过程中,队列中最多有 N − 1 N−1 N−1 个节点,需要 O ( N ) O(N) O(N) 的空间。