0785. 判断二分图【中等】
1. 📝 题目描述
存在一个 无向图,图中有 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:

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

txt
输入:graph = [[1,3],[0,2],[1,3],[0,2]]
输出:true
解释:
可以将节点分成两组: {0, 2} 和 {1, 3}。1
2
3
4
5
2
3
4
5
提示:
graph.length == n1 <= n <= 1000 <= graph[u].length < n0 <= graph[u][i] <= n - 1graph[u]不会包含ugraph[u]的所有值 互不相同- 如果
graph[u]包含v,那么graph[v]也会包含u
2. 🎯 s.1 - BFS 染色
c
bool isBipartite(int** graph, int graphSize, int* graphColSize) {
int* color = (int*)calloc(graphSize, sizeof(int));
int* queue = (int*)malloc(sizeof(int) * graphSize);
bool res = true;
for (int i = 0; i < graphSize && res; i++) {
if (color[i] != 0) continue;
int front = 0, back = 0;
queue[back++] = i;
color[i] = 1;
while (front < back && res) {
int u = queue[front++];
for (int j = 0; j < graphColSize[u]; j++) {
int v = graph[u][j];
if (color[v] == 0) { color[v] = -color[u]; queue[back++] = v; }
else if (color[v] == color[u]) { res = false; break; }
}
}
}
free(color); free(queue);
return res;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
js
/**
* @param {number[][]} graph
* @return {boolean}
*/
var isBipartite = function (graph) {
const n = graph.length
const color = new Array(n).fill(0) // 0:未染色 1:红 -1:蓝
for (let i = 0; i < n; i++) {
if (color[i] !== 0) continue
const queue = [i]
color[i] = 1
while (queue.length) {
const u = queue.shift()
for (const v of graph[u]) {
if (color[v] === 0) {
color[v] = -color[u]
queue.push(v)
} else if (color[v] === color[u]) {
return false
}
}
}
}
return true
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
py
class Solution:
def isBipartite(self, graph: List[List[int]]) -> bool:
from collections import deque
n = len(graph)
color = [0] * n
for i in range(n):
if color[i] != 0:
continue
queue = deque([i])
color[i] = 1
while queue:
u = queue.popleft()
for v in graph[u]:
if color[v] == 0:
color[v] = -color[u]
queue.append(v)
elif color[v] == color[u]:
return False
return True1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- 时间复杂度:
,其中 V 是节点数,E 是边数 - 空间复杂度:
算法思路:
- 用 BFS 对每个连通分量进行二色染色
- 若相邻节点同色则不是二分图