Leetcode_785_Is Graph Bipartite?
lihe opened this issue · 0 comments
lihe commented
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 containi
or duplicate values.- The graph is undirected: if any element
j
is ingraph[i]
, theni
will be ingraph[j]
.
解题思路:深度优先着色;使用数组记录每个节点的颜色,颜色可以是0,1,-1(未着色);遍历每个节点,对每个未着色的节点着色,从该节点进行深度优先搜索着色,每个邻接点与当前节点着相反的颜色,如果当邻节点已经着色,且颜色与当前节点相同,那么不是二分图。
class Solution {
public boolean isBipartite(int[][] graph) {
int n = graph.length;
int[] color = new int[n];
Arrays.fill(color, -1);
for(int start = 0; start < n; start++){
if(color[start] == -1){
Stack<Integer> stack = new Stack<>();
stack.push(start);
color[start] = 0;
while (!stack.empty()){
Integer node = stack.pop();
for(int neigh: graph[node]){
if(color[neigh] == -1){
stack.push(neigh);
color[neigh] = color[node] ^ 1;
}
else if(color[neigh] == color[node])
return false;
}
}
}
}
return true;
}
}
class Solution {
public boolean isBipartite(int[][] graph) {
if (graph == null || graph.length == 0) return false;
int v = graph.length;
int[] colors = new int[v]; // 0未被染色, 1黑 2白
// 要考虑非连通图, 所以要遍历每一个结点
for (int i = 0; i < v; i++) {
// lastColor为0
if (!dfs(graph, i, colors, 0)) return false;
}
return true;
}
private boolean dfs(int[][] graph, int i, int[] colors, int lastColor) {
// 注意,被染色的就不要继续染色了(因为这是自底向上的,被染色的点,其相连的节点肯定被染色了)
// 如果继续对被染色的节点染色,就会导致死循环
if (colors[i] != 0) return colors[i] != lastColor;
// 未被染色,染成与相邻结点不同的颜色(lastColor为0时,就染成1)
colors[i] = lastColor == 1 ? 2 : 1;
for (int j = 0; j < graph[i].length; j++) {
if (!dfs(graph, graph[i][j], colors, colors[i])) return false;
}
return true;
}
}