判断二分图
难度:
标签:
题目描述
存在一个 无向图 ,图中有
n
个节点。其中每个节点都有一个介于 0
到 n - 1
之间的唯一编号。给你一个二维数组 graph
,其中 graph[u]
是一个节点数组,由节点 u
的邻接节点组成。形式上,对于 graph[u]
中的每个 v
,都存在一条位于节点 u
和节点 v
之间的无向边。该无向图同时具有以下属性:
- 不存在自环(
graph[u]
不包含u
)。 - 不存在平行边(
graph[u]
不包含重复值)。 - 如果
v
在graph[u]
内,那么u
也应该在graph[v]
内(该图是无向图) - 这个图可能不是连通图,也就是说两个节点
u
和v
之间可能不存在一条连通彼此的路径。
二分图 定义:如果能将一个图的节点集合分割成两个独立的子集 A
和 B
,并使图中的每一条边的两个节点一个来自 A
集合,一个来自 B
集合,就将这个图称为 二分图 。
如果图是二分图,返回 true
;否则,返回 false
。
示例 1:

输入:graph = [[1,2,3],[0,2],[0,1,3],[0,2]]
输出:false
解释:不能将节点分割成两个独立的子集,
以使每条边都连通一个子集中的一个节点与另一个子集中的一个节点。
示例 2:

输入:graph = [[1,3],[0,2],[1,3],[0,2]]
输出:true
解释:可以将节点分成两组: {0, 2} 和 {1, 3} 。
提示:
graph.length == n
1 <= n <= 100
0 <= graph[u].length < n
0 <= graph[u][i] <= n - 1
graph[u]
不会包含u
graph[u]
的所有值 互不相同- 如果
graph[u]
包含v
,那么graph[v]
也会包含u
代码结果
运行时间: 26 ms, 内存: 16.8 MB
/*
* Problem: Determine if a given undirected graph is bipartite.
* Approach: Use Stream API for the initialization and processing of nodes.
* We use BFS with a queue to assign colors and check conditions.
*/
import java.util.*;
import java.util.stream.IntStream;
public class Solution {
public boolean isBipartite(int[][] graph) {
int n = graph.length;
int[] colors = IntStream.generate(() -> 0).limit(n).toArray();
for (int i = 0; i < n; i++) {
if (colors[i] == 0) { // Node is uncolored
if (!bfsCheck(graph, i, colors)) {
return false;
}
}
}
return true;
}
private boolean bfsCheck(int[][] graph, int start, int[] colors) {
Queue<Integer> queue = new LinkedList<>();
queue.offer(start);
colors[start] = 1; // Start coloring with color A
while (!queue.isEmpty()) {
int node = queue.poll();
for (int neighbor : graph[node]) {
if (colors[neighbor] == 0) { // If the neighbor is uncolored
colors[neighbor] = -colors[node]; // Assign opposite color
queue.offer(neighbor);
} else if (colors[neighbor] == colors[node]) { // If the neighbor has the same color
return false; // Not a bipartite graph
}
}
}
return true;
}
}
解释
方法:
这个题解使用了深度优先搜索(DFS)的方法来判断图是否为二分图。基本思路是:对图进行遍历,将相邻的节点着不同的颜色(用1和-1表示)。如果在遍历的过程中,发现某个节点的所有相邻节点都已经着色,并且有相同颜色的相邻节点,则说明不是二分图,返回False。如果遍历完整个图,都没有发现相邻节点有相同颜色的情况,则说明是二分图,返回True。
时间复杂度:
O(节点数+边数)
空间复杂度:
O(节点数)
代码细节讲解
🦆
题解中使用的DFS方法是如何处理图中的不连通情况的?
▷🦆
为什么在选择着色方式时使用了1和-1,而不是使用其他数字或者颜色标识?
▷🦆
在DFS函数中,如果已经为一个节点着色,再次遇到该节点时如何处理?
▷🦆
题解提到每个节点最多被访问一次,这是否意味着算法能有效处理大型稀疏或密集图?
▷