Given a graph
, return true
if and only if it is bipartite.
Recall that a graph is bipartite if we can split it's set of nodes into two independent subsets A and B such that every edge in the graph has one node in A and another node in B.
The graph is given in the following form: graph[i]
is a list of indexes j
for which the edge between nodes i
and j
exists. Each node is an integer between 0
and graph.length - 1
. There are no self edges or parallel edges: graph[i]
does not contain i
, and it doesn't contain any element twice.
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, 3}.
Example 2:
Input: [[1,2,3], [0,2], [0,1,3], [0,2]]
Output: false
Explanation:
The graph looks like this:
0----1
| \ |
| \ |
3----2
We cannot find a way to divide the set of nodes into two independent ubsets.
Note:
graph
will have length in range[1, 100]
.graph[i]
will contain integers in range[0, graph.length - 1]
.graph[i]
will not containi
or duplicate values.
最开始什么也没想,就一个个染色过去:
class Solution:
def isBipartite(self, graph):
"""
:type graph: List[List[int]]
:rtype: bool
"""
visit, mark, l = set(), [-1]*len(graph), []
start = 0
while start<len(graph) and not graph[start]:
visit.add(start)
start+=1
if start==len(graph): return True
visit.add(start)
mark[start] = 1
for t in graph[start]:
l.append(t)
mark[t]=2
start += 1
while l:
p = l.pop()
if p in visit: continue
visit.add(p)
for t in graph[p]:
if mark[p]==mark[t]: return False
mark[t] = 1 if mark[p]==2 else 2
l.append(t)
return True
但是可能有很多个独立不重叠的集合,开始的思路是在while循环外在加上一个循环,判断下一个没有被标记的是哪个。
猛然记起这不就是之前一直写的外面套有一层循环的BFS吗?
class Solution:
def isBipartite(self, graph):
"""
:type graph: List[List[int]]
:rtype: bool
"""
visit, mark, l = set(), [-1]*len(graph), []
for start in range(len(graph)):
if not graph[start]:
visit.add(start)
continue
mark[start] = 1
for t in graph[start]:
l.append(t)
mark[t]=2
while l:
p = l.pop()
if p in visit: continue
visit.add(p)
for t in graph[p]:
if mark[p]==mark[t]: return False
mark[t] = 1 if mark[p]==2 else 2
l.append(t)
return True
想到了BFS,DFS版本也就容易了,又不是求最小步数什么的,DFS递归写得多爽
唯一需要注意的是某个节点染的颜色需要一个维护一个数组,某个节点是否被visited过仍然需要维护一个数组
class Solution:
def isBipartite(self, graph):
"""
:type graph: List[List[int]]
:rtype: bool
"""
visit, mark = set(), [-1]*len(graph)
def dfs(s):
if s in visit: return True
visit.add(s)
for t in graph[s]:
if mark[s]==mark[t]: return False
mark[t] = 1 if mark[s]==2 else 2
if not dfs(t): return False
return True
for start in range(len(graph)):
mark[start] = 1
if not dfs(start): return False
return True