代码改变世界

[LeetCode] 785. Is Graph Bipartite?_Medium tag: DFS, BFS

2018-07-06 09:25  Johnson_强生仔仔  阅读(414)  评论(0编辑  收藏  举报

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 contain i or duplicate values.
  • The graph is undirected: if any element j is in graph[i], then i will be in graph[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)

 1 class Solution:
 2     def isBipartite(self, graph):
 3         d = {}
 4         for i in range(len(graph)):
 5             if i not in d:
 6                 d[i] = 1
 7                 stack = [i]
 8                 while stack:
 9                     node = stack.pop()
10                     for each in graph[node]:
11                         if each not in d:
12                             d[each] = d[node]*(-1)
13                             stack.append(each)
14                         elif d[each] == d[node]:
15                             return False
16         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