[Leetcode] 785. Is Graph Bipartite? 解题报告

题目

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].

思路

我们可以将这个图问题转换成为染色问题:如果这个图是二分图,那么它必然可以被二着色。所以我们每次遇到一个结点时,首先检查它是否已经被着色;如果是,则看是否和前面的着色相兼容;如果是则继续,否则就说明该图不是二分图,返回false。这种图的遍历问题一般既可以用BFS也可以用DFS,下面我们分别给出两种方法的解释和源代码。

1、BFS:逐个检查每个节点是否已经被染色,如果没有被染色,则首先将其染为颜色0,然后采用BFS依次对和它相连的节点进行检查和染色。如果相连的节点没有被染色,则将其染为另外一种颜色;否则就检查染色是否和原来兼容,如果不兼容则立即返回false。注意当从一个结点开始的的BFS搜索全部结束时,和该结点有直接或者间接连接关系的所有结点都会已经被染色了,所以当开始对下一个节点染色的时候,我们就可以大胆将其染为颜色0。这样当整个染色完成的时候,如果没有发现染色冲突,则说明原来的图就是二分图。

2、DFS:思路其实和BFS非常一致,只不过采用了DFS的搜索策略:首先检查该结点是否已经被染色,如果是,则返回其是否兼容的信息;否则就给结点染色,并且采用DFS的策略对和其直接或者间接相连的所有结点染色。整个过程中如果发现冲突就提前返回false;否则在最后返回true。

代码

1、BFS:

class Solution {
public:
    bool isBipartite(vector>& graph) {
        int n = graph.size();
        vector colors(n, -1);
        for (int i = 0; i < n; ++i) {
            if (colors[i] == -1) {          // the node i has not been colored, so color it
                if (!BFS(graph, colors, 0, i)) {
                    return false;
                }
            }
        }
        return true;
    }
private:
    bool BFS(vector> &graph, vector &colors, int color, int node) {
        queue q;
        q.push(node);
        colors[node] = color;
        while (!q.empty()) {
            int i = q.front(), c = colors[i];
            q.pop();
            for (auto next : graph[i]) {
                if (colors[next] == -1) {   // not colored, so color it using another color
                    q.push(next);
                    colors[next] = 1 - c;
                }
                else {                      // already colored, so check whether it is compatible
                    if (colors[next] != 1 - c) {
                        return false;
                    }
                }
            }
        }
        return true;
    } 
};

2、DFS:

class Solution {
public:
    bool isBipartite(vector>& graph) {
        int n = graph.size();
        vector colors(n, -1);      // colors[i] == -1 mean has not been colored
        for (int i = 0; i < n; ++i) {   // try to color this the i-th node
            if (colors[i] == -1 && !DFS(graph, colors, 0, i)) {
                return false;
            }
        }
        return true;
    }
private:
    bool DFS(vector> &graph, vector &colors, int color, int node) {
        if (colors[node] != -1) {       // has been colored, so check whether compatible
            return colors[node] == color;
        }
        colors[node] = color;           // color the first node
        for (int next : graph[node]) {  // color other nodes who are connected with node
            if (!DFS(graph, colors, 1 - color, next)) {
                return false;
            }
        }
        return true;
    }
};

你可能感兴趣的:(IT公司面试习题)