Given an undirected 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 subsets.
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. - The graph is undirected: if any element
j
is ingraph[i]
, theni
will be ingraph[j]
.
这个题目实际意思就是说可不可以用两种颜色将graph都涂上颜色. 最初的想法是BFS, 我的前提假设是给的这个graph的所有元素都是连通的, 然后将0放入, 接着BFS遍历遍历的点, 如果点的neighbor没有visited过的, 就将neighbor设为跟点不一样的颜色, 并append进入queue, 如果visited过, 看颜色是否跟点一样,如果一样,return False.
但是提交之后发现有的test case不行, 因为给的graph允许一些单独的点存在, 也就是说不一定所有的点都要连通, 那么我初始化的时候就把0 - n-1 个点都append进入queue里面, 但是发现如果用BFS的话, 我们在初始化每个点的时候有可能之前的路径还没走完, 所以需要用DFS, 思路跟以上BFS类似, 只是把stack初始化的时候把0 - n-1个点都append进去.
updated:
我们还是用DFS, 但是除了单纯的把0 - n-1个点都append进入stack里面, 我们可以用一个dictionary去找看如果还有点不在里面的, 我们就DFS遍历一遍.跟之前类似的判断.
1. Constraints
1) size of graph [1,100]
2) graph[i] size [0,graph size -1] and no duplicates
3) undirected
4) very important! no need to connect with every node!
2. Ideas
DFS T: O(n) S: O(n)
1) 空dictionary , d
2) for i in range(len(graph)), 如果不在d里面, 将d[i] = 1, 用DFS, 将所有neigbor设为-1, 如果没有在d里面的, 如果在的, 监测跟d[i] 是否一样, 如果一样返回False
3) 结束for loop, 返回True
3. Code
1)
class Solution(object):
def isBipartite(self, graph):
"""
:type graph: List[List[int]]
:rtype: bool
"""
n, colorMap = len(graph), collections.Counter()
def dfs(i, color):
if colorMap[i] == color: return True
if colorMap[i] == color * (-1): return False
colorMap[i] = color
for neig in graph[i]:
if not dfs(neig, color * (-1)):
return False
return True
for i in range(n):
if colorMap[i] != 0:
continue
if not dfs(i, 1):
return False
return True
2)
class Solution:
def isBipartite(self, graph):
d = {}
for i in range(len(graph)):
if i not in d:
d[i] = 1
stack = [i]
while stack:
node = stack.pop()
for each in graph[node]:
if each not in d:
d[each] = d[node]*(-1)
stack.append(each)
elif d[each] == d[node]:
return False
return True
4. Test cases
1) [[1,3], [0,2], [1,3], [0,2]] => True 2)[[1,2,3], [0,2], [0,1,3], [0,2]] => False