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.
M1: BFS
time: O(V + E), space: O(V)
class Solution { public boolean isBipartite(int[][] graph) { int[] visited = new int[graph.length]; for(int i = 0; i < graph.length; i++) { if(!BFS(graph, i, visited)) { return false; } } return true; } private boolean BFS(int[][] graph, int node, int[] visited) { if(visited[node] != 0) { return true; } Queue<Integer> q = new LinkedList<>(); q.offer(node); visited[node] = 1; while(!q.isEmpty()) { int cur = q.poll(); int curColor = visited[cur]; int neiColor = -curColor; for(int nei : graph[cur]) { if(visited[nei] == 0) { visited[nei] = neiColor; q.offer(nei); } else if(visited[nei] != neiColor) { return false; } } } return true; } }
M2: DFS
Graph Coloring (by DFS/BFS): color a node as red, and then color all its neighbors as blue recursively. if there's any conflict, return false.
染色法 Graph Coloring (by DFS)
将相连的两个顶点染成不同的颜色,一旦在染的过程中发现有两连的两个顶点已经被染成相同的颜色,说明不是二分图。
-> 使用两种颜色,分别用1和-1来表示,初始时每个顶点用0表示未染色
-> 遍历每一个顶点,如果该顶点未被访问过,调用递归函数,如果返回false,说明不是二分图,直接返回false;
如果循环退出后没有返回false,则返回true。
-> 在递归函数中,如果当前顶点已经染色:如果该顶点的颜色和将要染的颜色相同,则返回true;否则返回false。
如果没被染色,则将当前顶点染色(-1*color: 将相邻点染成不同颜色),然后再遍历与该顶点相连的所有的顶点,调用递归函数,如果返回false了,则当前递归函数的返回false,循环结束返回true.
time: O(V+E), space: O(V+E)
class Solution { int[] colors; public boolean isBipartite(int[][] graph) { int n = graph.length; colors = new int[n]; for(int i = 0; i < n; i++) { if(colors[i] == 0 && !dfs(graph, i, 1)) return false; } return true; } private boolean dfs(int[][] graph, int node, int color) { if(colors[node] != 0) return colors[node] == color ? true: false; else { colors[node] = color; for(int j : graph[node]) { if(!dfs(graph, j, -color)) return false; } } return true; } }