https://leetcode.com/problems/is-graph-bipartite/description/
X. https://leetcode.com/problems/is-graph-bipartite/discuss/115487/Java-Clean-DFS-solution-with-Explanation
Initialize a color[] array for each node. Here are three states for colors[] array:
For each node,
X. BFS
https://leetcode.com/problems/is-graph-bipartite/discuss/115528/Java-BFS-with-explanation
Can we divide the node in two sets such that no two nodes in same set are linked. This was the problem. But sometimes, graph can be a forest. So, we need to check if every node has been processed/colored/discovered or not. O(E)
https://leetcode.com/problems/is-graph-bipartite/discuss/120218/Java-Short-Iterative-Solution
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]
.
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:
-1: Haven't been colored.
0: Blue.
1: Red.
For each node,
- If it hasn't been colored, use a color to color it. Then use the other color to color all its adjacent nodes (DFS).
- 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. (Please forgive my english... Hope you can understand it.)
public boolean isBipartite(int[][] graph) {
int n = graph.length;
int[] colors = new int[n];
Arrays.fill(colors, -1);
for (int i = 0; i < n; i++) { //This graph might be a disconnected graph. So check each unvisited node.
if (colors[i] == -1 && !validColor(graph, colors, 0, i)) {
return false;
}
}
return true;
}
public boolean validColor(int[][] graph, int[] colors, int color, int node) {
if (colors[node] != -1) {
return colors[node] == color;
}
colors[node] = color;
for (int next : graph[node]) {
if (!validColor(graph, colors, 1 - color, next)) {
return false;
}
}
return true;
}
https://blog.csdn.net/u014688145/article/details/79334650
二分图满足存在子集A和子集B,使得从A出发的边只能连接到B,B出发的边只能连接到A。换句话说,A出发的边不能连到A中的元素。B同理,采用染色法,因为相连的边一定是互异的,如果在不断染色的过程当中,出现冲突的情况,即返回false,全部染色完毕未发现冲突则返回true。
public boolean isBipartite(int[][] input) {
if (input == null) {
return true;
}
Map<Integer, Boolean> nodeColors = new HashMap<>();
for (int i = 0; i < input.length; i++) {
if (!nodeColors.containsKey(i)) {
if (hasConflict(input, i, nodeColors)) {
// System.out.println(nodeColors);
return false;
}
}
}
// System.out.println(nodeColors);
return true;
}
private boolean hasConflict(int[][] input, int curNode, Map<Integer, Boolean> nodeColors) {
if (!nodeColors.containsKey(curNode)) {
nodeColors.put(curNode, true);
}
boolean curColor = nodeColors.get(curNode);
for (int dst : input[curNode]) {
if (nodeColors.containsKey(dst)) {
if (nodeColors.get(dst) == curColor) {
return true; // the meaning of return value
}
continue;
}
nodeColors.put(dst, !curColor);
if (hasConflict(input, dst, nodeColors)) {
return true;
}
}
return false;
}
X. BFS
https://leetcode.com/problems/is-graph-bipartite/discuss/115528/Java-BFS-with-explanation
Can we divide the node in two sets such that no two nodes in same set are linked. This was the problem. But sometimes, graph can be a forest. So, we need to check if every node has been processed/colored/discovered or not. O(E)
https://leetcode.com/problems/is-graph-bipartite/discuss/120218/Java-Short-Iterative-Solution
public boolean isBipartite(int[][] g) {
int[] colors = new int[g.length];
for (int i = 0; i < g.length; i++)
if (colors[i] == 0) {
Queue<Integer> q = new LinkedList<>();
q.add(i);
colors[i] = 1;
while (!q.isEmpty()) {
Integer node = q.poll();
for (int adjacent : g[node])
if (colors[adjacent] == colors[node])
return false;
else if (colors[adjacent] == 0) {
q.add(adjacent);
colors[adjacent] = -colors[node];
}
}
}
return true;
}
https://leetcode.com/problems/is-graph-bipartite/discuss/115503/java-BFS public boolean isBipartite(int[][] graph) {
//BFS
// 0(not meet), 1(black), 2(white)
int[] visited = new int[graph.length];
for (int i = 0; i < graph.length; i++) {
if (graph[i].length != 0 && visited[i] == 0) {
visited[i] = 1;
Queue<Integer> q = new LinkedList<>();
q.offer(i);
while(! q.isEmpty()) {
int current = q.poll();
for (int c: graph[current]) {
if (visited[c] == 0) {
visited[c] = (visited[current] == 1) ? 2 : 1;
q.offer(c);
} else {
if (visited[c] == visited[current]) return false;
}
}
}
}
}
return true;
}
https://leetcode.com/problems/is-graph-bipartite/discuss/115528/Java-BFS-with-explanation