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.
分析:

Our goal is trying to use two colors to color the graph and see if there are any adjacent nodes having the same color.
Initialize a color[] array for each node. Here are three states for colors[] array:
0: Haven't been colored yet.
1: Blue.
-1: Red.
For each node,

  1. If it hasn't been colored, use a color to color it. Then use the other color to color all its adjacent nodes (DFS).
  2. If it has been colored, check if the current color is the same as the color that is going to be used to color it. 

DFS

 1 class Solution {
 2     public boolean isBipartite(int[][] graph) {
 3         int n = graph.length;
 4         // 0 unvisited 1 red -1 blue
 5         int[] colors = new int[n];            
 6         //This graph might be a disconnected graph. So check each unvisited node.
 7         for (int i = 0; i < n; i++) {              
 8             if (colors[i] == 0) {
 9                 if (!validColor(graph, colors, 1, i)) {
10                     return false;
11                 }
12             }
13         }
14         return true;
15     }
16     
17     public boolean validColor(int[][] graph, int[] colors, int color, int node) {
18         colors[node] = color;       
19         for (int next : graph[node]) {
20             if (colors[next] == 0 && !validColor(graph, colors, -color, next)) {
21                 return false;
22             } else if (colors[next] == colors[node]) {
23                 return false;
24             }
25         }
26         return true;
27     }
28 }

BFS

 1 class Solution {
 2     public boolean isBipartite(int[][] graph) {
 3         // 0: unvisited; 1: black; 2: white
 4         int[] status = new int[graph.length];
 5         // for loop is used to handle unconnected components in the graph
 6         for (int i = 0; i < graph.length; i++) {
 7             if (status[i] == 0) {
 8                 status[i] = 1;
 9                 if (!bfs(i, status, graph)) {
10                     return false;
11                 };  
12             }
13         }
14         return true;
15     }
16 
17     private boolean bfs(int i, int[] status, int[][] graph) {
18         Queue<Integer> queue = new LinkedList<>();
19         queue.offer(i);
20         while (!queue.isEmpty()) {
21             int current = queue.poll();
22             for (int neighbor : graph[current]) {
23                 if (status[neighbor] == 0) {
24                     status[neighbor] = (status[current] == 1) ? 2 : 1;
25                     queue.offer(neighbor);
26                 } else {
27                     if (status[neighbor] == status[current]) return false;
28                 }
29             }
30         }
31         return true;
32     }
33 }

 

posted @ 2019-08-29 13:31  北叶青藤  阅读(314)  评论(0)    收藏  举报