Skip to content

Commit d44614a

Browse files
committed
feat: add solutions to lc problem: No.0785
No.0785.Is Graph Bipartite
1 parent 8e1d795 commit d44614a

File tree

9 files changed

+335
-98
lines changed

9 files changed

+335
-98
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
- [最低成本联通所有城市](/solution/1100-1199/1135.Connecting%20Cities%20With%20Minimum%20Cost/README.md) - 最小生成树、Kruskal 算法、并查集
119119
- [水资源分配优化](/solution/1100-1199/1168.Optimize%20Water%20Distribution%20in%20a%20Village/README.md) - 最小生成树、Kruskal 算法、并查集
120120
- [找到最小生成树里的关键边和伪关键边](/solution/1400-1499/1489.Find%20Critical%20and%20Pseudo-Critical%20Edges%20in%20Minimum%20Spanning%20Tree/README.md) - 最小生成树、Kruskal 算法、并查集
121+
- [判断二分图](/solution/0700-0799/0785.Is%20Graph%20Bipartite/README.md) - 染色法判定二分图、并查集
121122

122123
<!-- 待补充
123124
### 6. 数学知识

README_EN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ Complete solutions to [LeetCode](https://leetcode.com/problemset/all/), [LCOF](h
114114
- [Connecting Cities With Minimum Cost](/solution/1100-1199/1135.Connecting%20Cities%20With%20Minimum%20Cost/README_EN.md) - Minimum Spanning Tree, Kruskal's algorithm
115115
- [Optimize Water Distribution in a Village](/solution/1100-1199/1168.Optimize%20Water%20Distribution%20in%20a%20Village/README_EN.md) - Minimum Spanning Tree, Kruskal's algorithm, Union find
116116
- [Find Critical and Pseudo-Critical Edges in Minimum Spanning Tree](/solution/1400-1499/1489.Find%20Critical%20and%20Pseudo-Critical%20Edges%20in%20Minimum%20Spanning%20Tree/README_EN.md) - Minimum Spanning Tree, Kruskal's algorithm, Union find
117+
- [Is Graph Bipartite?](/solution/0700-0799/0785.Is%20Graph%20Bipartite/README_EN.md) - Graph coloring, Union find
117118

118119
<!--
119120
### 6. Mathematical Knowledge

solution/0700-0799/0785.Is Graph Bipartite/README.md

Lines changed: 142 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,13 @@
5353

5454
<!-- 这里可写通用的实现逻辑 -->
5555

56-
并查集。
56+
**方法一:染色法判定二分图**
5757

58-
并查集模板:
58+
遍历所有节点进行染色,比如初始为白色,DFS 对节点相邻的点染上另外一种颜色。如果要染色某节点时,要染的目标颜色和该节点的已经染过的颜色不同,则说明不能构成二分图。
59+
60+
**方法二:并查集**
61+
62+
对于本题,如果是二分图,那么图中每个顶点的所有邻接点都应该属于同一集合,且不与顶点处于同一集合,因此我们可以使用并查集。遍历图中每个顶点,如果发现存在当前顶点与对应的邻接点处于同一个集合,说明不是二分图。否则将当前节点的邻接点相互进行合并。以下是并查集模板。
5963

6064
模板 1——朴素并查集:
6165

@@ -114,14 +118,33 @@ p[find(a)] = find(b)
114118
d[find(a)] = distance
115119
```
116120

117-
对于本题,如果是二分图,那么图中每个顶点的所有邻接点都应该属于同一集合,且不与顶点处于同一集合,因此我们可以使用并查集。遍历图中每个顶点,如果发现存在当前顶点与对应的邻接点处于同一个集合,说明不是二分图。否则将当前节点的邻接点相互进行合并。
118-
119121
<!-- tabs:start -->
120122

121123
### **Python3**
122124

123125
<!-- 这里可写当前语言的特殊实现逻辑 -->
124126

127+
```python
128+
class Solution:
129+
def isBipartite(self, graph: List[List[int]]) -> bool:
130+
def dfs(u, c):
131+
color[u] = c
132+
for v in graph[u]:
133+
if not color[v]:
134+
if not dfs(v, 3 - c):
135+
return False
136+
elif color[v] == c:
137+
return False
138+
return True
139+
140+
n = len(graph)
141+
color = [0] * n
142+
for i in range(n):
143+
if not color[i] and not dfs(i, 1):
144+
return False
145+
return True
146+
```
147+
125148
```python
126149
class Solution:
127150
def isBipartite(self, graph: List[List[int]]) -> bool:
@@ -130,8 +153,7 @@ class Solution:
130153
p[x] = find(p[x])
131154
return p[x]
132155

133-
n = len(graph)
134-
p = list(range(n))
156+
p = list(range(len(graph)))
135157
for u, g in enumerate(graph):
136158
for v in g:
137159
if find(u) == find(v):
@@ -144,6 +166,39 @@ class Solution:
144166

145167
<!-- 这里可写当前语言的特殊实现逻辑 -->
146168

169+
```java
170+
class Solution {
171+
private int[] color;
172+
private int[][] g;
173+
174+
public boolean isBipartite(int[][] graph) {
175+
int n = graph.length;
176+
color = new int[n];
177+
g = graph;
178+
for (int i = 0; i < n; ++i) {
179+
if (color[i] == 0 && !dfs(i, 1)) {
180+
return false;
181+
}
182+
}
183+
return true;
184+
}
185+
186+
private boolean dfs(int u, int c) {
187+
color[u] = c;
188+
for (int v : g[u]) {
189+
if (color[v] == 0) {
190+
if (!dfs(v, 3 - c)) {
191+
return false;
192+
}
193+
} else if (color[v] == c) {
194+
return false;
195+
}
196+
}
197+
return true;
198+
}
199+
}
200+
```
201+
147202
```java
148203
class Solution {
149204
private int[] p;
@@ -177,6 +232,33 @@ class Solution {
177232

178233
### **C++**
179234

235+
```cpp
236+
class Solution {
237+
public:
238+
bool isBipartite(vector<vector<int>>& graph) {
239+
int n = graph.size();
240+
vector<int> color(n);
241+
for (int i = 0; i < n; ++i)
242+
if (!color[i] && !dfs(i, 1, color, graph))
243+
return false;
244+
return true;
245+
}
246+
247+
bool dfs(int u, int c, vector<int>& color, vector<vector<int>>& g) {
248+
color[u] = c;
249+
for (int& v : g[u])
250+
{
251+
if (!color[v])
252+
{
253+
if (!dfs(v, 3 - c, color, g)) return false;
254+
}
255+
else if (color[v] == c) return false;
256+
}
257+
return true;
258+
}
259+
};
260+
```
261+
180262
```cpp
181263
class Solution {
182264
public:
@@ -207,6 +289,33 @@ public:
207289
208290
### **Go**
209291
292+
```go
293+
func isBipartite(graph [][]int) bool {
294+
n := len(graph)
295+
color := make([]int, n)
296+
var dfs func(u, c int) bool
297+
dfs = func(u, c int) bool {
298+
color[u] = c
299+
for _, v := range graph[u] {
300+
if color[v] == 0 {
301+
if !dfs(v, 3-c) {
302+
return false
303+
}
304+
} else if color[v] == c {
305+
return false
306+
}
307+
}
308+
return true
309+
}
310+
for i := range graph {
311+
if color[i] == 0 && !dfs(i, 1) {
312+
return false
313+
}
314+
}
315+
return true
316+
}
317+
```
318+
210319
```go
211320
func isBipartite(graph [][]int) bool {
212321
n := len(graph)
@@ -239,12 +348,11 @@ func isBipartite(graph [][]int) bool {
239348
function isBipartite(graph: number[][]): boolean {
240349
const n = graph.length;
241350
let valid = true;
242-
let colors = new Array(n).fill(0);
243351
// 0 未遍历, 1 红色标记, 2 绿色标记
244-
352+
let colors = new Array(n).fill(0);
245353
function dfs(idx: number, color: number, graph: number[][]) {
246354
colors[idx] = color;
247-
const nextColor = color == 1 ? 2 : 1;
355+
const nextColor = 3 - color;
248356
for (let j of graph[idx]) {
249357
if (!colors[j]) {
250358
dfs(j, nextColor, graph);
@@ -265,6 +373,31 @@ function isBipartite(graph: number[][]): boolean {
265373
}
266374
```
267375

376+
```ts
377+
function isBipartite(graph: number[][]): boolean {
378+
const n = graph.length;
379+
let p = new Array(n);
380+
for (let i = 0; i < n; ++i) {
381+
p[i] = i;
382+
}
383+
function find(x) {
384+
if (p[x] != x) {
385+
p[x] = find(p[x]);
386+
}
387+
return p[x];
388+
}
389+
for (let u = 0; u < n; ++u) {
390+
for (let v of graph[u]) {
391+
if (find(u) == find(v)) {
392+
return false;
393+
}
394+
p[find(v)] = find(graph[u][0]);
395+
}
396+
}
397+
return true;
398+
}
399+
```
400+
268401
### **...**
269402

270403
```

0 commit comments

Comments
 (0)