Skip to content

Commit c2aa916

Browse files
authored
feat: add solutions to lc problem: No.0785 (#4093)
No.0785.Is Graph Bipartite
1 parent ebe1567 commit c2aa916

14 files changed

+323
-521
lines changed

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

+109-217
Large diffs are not rendered by default.

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

+103-144
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ tags:
6666

6767
<!-- solution:start -->
6868

69-
### Solution 1
69+
### Solution 1: Coloring Method to Determine Bipartite Graph
70+
71+
Traverse all nodes for coloring. For example, initially color them white, and use DFS to color the adjacent nodes with another color. If the target color to be colored is different from the color that the node has already been colored, it means that it cannot form a bipartite graph.
72+
73+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the number of nodes.
7074

7175
<!-- tabs:start -->
7276

@@ -75,20 +79,17 @@ tags:
7579
```python
7680
class Solution:
7781
def isBipartite(self, graph: List[List[int]]) -> bool:
78-
def dfs(u, c):
79-
color[u] = c
80-
for v in graph[u]:
81-
if not color[v]:
82-
if not dfs(v, 3 - c):
83-
return False
84-
elif color[v] == c:
82+
def dfs(a: int, c: int) -> bool:
83+
color[a] = c
84+
for b in graph[a]:
85+
if color[b] == c or (color[b] == 0 and not dfs(b, -c)):
8586
return False
8687
return True
8788

8889
n = len(graph)
8990
color = [0] * n
9091
for i in range(n):
91-
if not color[i] and not dfs(i, 1):
92+
if color[i] == 0 and not dfs(i, 1):
9293
return False
9394
return True
9495
```
@@ -112,14 +113,10 @@ class Solution {
112113
return true;
113114
}
114115

115-
private boolean dfs(int u, int c) {
116-
color[u] = c;
117-
for (int v : g[u]) {
118-
if (color[v] == 0) {
119-
if (!dfs(v, 3 - c)) {
120-
return false;
121-
}
122-
} else if (color[v] == c) {
116+
private boolean dfs(int a, int c) {
117+
color[a] = c;
118+
for (int b : g[a]) {
119+
if (color[b] == c || (color[b] == 0 && !dfs(b, -c))) {
123120
return false;
124121
}
125122
}
@@ -161,15 +158,11 @@ public:
161158
func isBipartite(graph [][]int) bool {
162159
n := len(graph)
163160
color := make([]int, n)
164-
var dfs func(u, c int) bool
165-
dfs = func(u, c int) bool {
166-
color[u] = c
167-
for _, v := range graph[u] {
168-
if color[v] == 0 {
169-
if !dfs(v, 3-c) {
170-
return false
171-
}
172-
} else if color[v] == c {
161+
var dfs func(int, int) bool
162+
dfs = func(a, c int) bool {
163+
color[a] = c
164+
for _, b := range graph[a] {
165+
if color[b] == c || (color[b] == 0 && !dfs(b, -c)) {
173166
return false
174167
}
175168
}
@@ -189,65 +182,47 @@ func isBipartite(graph [][]int) bool {
189182
```ts
190183
function isBipartite(graph: number[][]): boolean {
191184
const n = graph.length;
192-
let valid = true;
193-
// 0 未遍历, 1 红色标记, 2 绿色标记
194-
let colors = new Array(n).fill(0);
195-
function dfs(idx: number, color: number, graph: number[][]) {
196-
colors[idx] = color;
197-
const nextColor = 3 - color;
198-
for (let j of graph[idx]) {
199-
if (!colors[j]) {
200-
dfs(j, nextColor, graph);
201-
if (!valid) return;
202-
} else if (colors[j] != nextColor) {
203-
valid = false;
204-
return;
185+
const color: number[] = Array(n).fill(0);
186+
const dfs = (a: number, c: number): boolean => {
187+
color[a] = c;
188+
for (const b of graph[a]) {
189+
if (color[b] === c || (color[b] === 0 && !dfs(b, -c))) {
190+
return false;
205191
}
206192
}
207-
}
208-
209-
for (let i = 0; i < n && valid; i++) {
210-
if (!colors[i]) {
211-
dfs(i, 1, graph);
193+
return true;
194+
};
195+
for (let i = 0; i < n; i++) {
196+
if (color[i] === 0 && !dfs(i, 1)) {
197+
return false;
212198
}
213199
}
214-
return valid;
200+
return true;
215201
}
216202
```
217203

218204
#### Rust
219205

220206
```rust
221207
impl Solution {
222-
#[allow(dead_code)]
223208
pub fn is_bipartite(graph: Vec<Vec<i32>>) -> bool {
224-
let mut graph = graph;
225209
let n = graph.len();
226-
let mut color_vec: Vec<usize> = vec![0; n];
227-
for i in 0..n {
228-
if color_vec[i] == 0 && !Self::traverse(i, 1, &mut color_vec, &mut graph) {
229-
return false;
210+
let mut color = vec![0; n];
211+
212+
fn dfs(a: usize, c: i32, graph: &Vec<Vec<i32>>, color: &mut Vec<i32>) -> bool {
213+
color[a] = c;
214+
for &b in &graph[a] {
215+
if color[b as usize] == c
216+
|| (color[b as usize] == 0 && !dfs(b as usize, -c, graph, color))
217+
{
218+
return false;
219+
}
230220
}
221+
true
231222
}
232-
true
233-
}
234223

235-
#[allow(dead_code)]
236-
fn traverse(
237-
v: usize,
238-
color: usize,
239-
color_vec: &mut Vec<usize>,
240-
graph: &mut Vec<Vec<i32>>,
241-
) -> bool {
242-
color_vec[v] = color;
243-
for n in graph[v].clone() {
244-
if color_vec[n as usize] == 0 {
245-
// This node hasn't been colored
246-
if !Self::traverse(n as usize, 3 - color, color_vec, graph) {
247-
return false;
248-
}
249-
} else if color_vec[n as usize] == color {
250-
// The color is the same
224+
for i in 0..n {
225+
if color[i] == 0 && !dfs(i, 1, &graph, &mut color) {
251226
return false;
252227
}
253228
}
@@ -262,7 +237,11 @@ impl Solution {
262237

263238
<!-- solution:start -->
264239

265-
### Solution 2
240+
### Solution 2: Union-Find
241+
242+
For this problem, if it is a bipartite graph, then all adjacent nodes of each vertex in the graph should belong to the same set and not be in the same set as the vertex. Therefore, we can use the union-find method. Traverse each vertex in the graph, and if it is found that the current vertex and its corresponding adjacent nodes are in the same set, it means that it is not a bipartite graph. Otherwise, merge the adjacent nodes of the current node.
243+
244+
The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Where $n$ is the number of nodes.
266245

267246
<!-- tabs:start -->
268247

@@ -271,17 +250,18 @@ impl Solution {
271250
```python
272251
class Solution:
273252
def isBipartite(self, graph: List[List[int]]) -> bool:
274-
def find(x):
253+
def find(x: int) -> int:
275254
if p[x] != x:
276255
p[x] = find(p[x])
277256
return p[x]
278257

279258
p = list(range(len(graph)))
280-
for u, g in enumerate(graph):
281-
for v in g:
282-
if find(u) == find(v):
259+
for a, bs in enumerate(graph):
260+
for b in bs:
261+
pa, pb = find(a), find(b)
262+
if pa == pb:
283263
return False
284-
p[find(v)] = find(g[0])
264+
p[pb] = find(bs[0])
285265
return True
286266
```
287267

@@ -297,13 +277,13 @@ class Solution {
297277
for (int i = 0; i < n; ++i) {
298278
p[i] = i;
299279
}
300-
for (int u = 0; u < n; ++u) {
301-
int[] g = graph[u];
302-
for (int v : g) {
303-
if (find(u) == find(v)) {
280+
for (int a = 0; a < n; ++a) {
281+
for (int b : graph[a]) {
282+
int pa = find(a), pb = find(b);
283+
if (pa == pb) {
304284
return false;
305285
}
306-
p[find(v)] = find(g[0]);
286+
p[pb] = find(graph[a][0]);
307287
}
308288
}
309289
return true;
@@ -323,25 +303,26 @@ class Solution {
323303
```cpp
324304
class Solution {
325305
public:
326-
vector<int> p;
327-
328306
bool isBipartite(vector<vector<int>>& graph) {
329307
int n = graph.size();
330-
p.resize(n);
331-
for (int i = 0; i < n; ++i) p[i] = i;
332-
for (int u = 0; u < n; ++u) {
333-
auto& g = graph[u];
334-
for (int v : g) {
335-
if (find(u) == find(v)) return 0;
336-
p[find(v)] = find(g[0]);
308+
vector<int> p(n);
309+
iota(p.begin(), p.end(), 0);
310+
auto find = [&](this auto&& find, int x) -> int {
311+
if (p[x] != x) {
312+
p[x] = find(p[x]);
313+
}
314+
return p[x];
315+
};
316+
for (int a = 0; a < n; ++a) {
317+
for (int b : graph[a]) {
318+
int pa = find(a), pb = find(b);
319+
if (pa == pb) {
320+
return false;
321+
}
322+
p[pb] = find(graph[a][0]);
337323
}
338324
}
339-
return 1;
340-
}
341-
342-
int find(int x) {
343-
if (p[x] != x) p[x] = find(p[x]);
344-
return p[x];
325+
return true;
345326
}
346327
};
347328
```
@@ -362,12 +343,13 @@ func isBipartite(graph [][]int) bool {
362343
}
363344
return p[x]
364345
}
365-
for u, g := range graph {
366-
for _, v := range g {
367-
if find(u) == find(v) {
346+
for a, bs := range graph {
347+
for _, b := range bs {
348+
pa, pb := find(a), find(b)
349+
if pa == pb {
368350
return false
369351
}
370-
p[find(v)] = find(g[0])
352+
p[pb] = find(bs[0])
371353
}
372354
}
373355
return true
@@ -379,22 +361,20 @@ func isBipartite(graph [][]int) bool {
379361
```ts
380362
function isBipartite(graph: number[][]): boolean {
381363
const n = graph.length;
382-
let p = new Array(n);
383-
for (let i = 0; i < n; ++i) {
384-
p[i] = i;
385-
}
386-
function find(x) {
387-
if (p[x] != x) {
364+
const p: number[] = Array.from({ length: n }, (_, i) => i);
365+
const find = (x: number): number => {
366+
if (x !== p[x]) {
388367
p[x] = find(p[x]);
389368
}
390369
return p[x];
391-
}
392-
for (let u = 0; u < n; ++u) {
393-
for (let v of graph[u]) {
394-
if (find(u) == find(v)) {
370+
};
371+
for (let a = 0; a < n; ++a) {
372+
for (const b of graph[a]) {
373+
const [pa, pb] = [find(a), find(b)];
374+
if (pa === pb) {
395375
return false;
396376
}
397-
p[find(v)] = find(graph[u][0]);
377+
p[pb] = find(graph[a][0]);
398378
}
399379
}
400380
return true;
@@ -405,50 +385,29 @@ function isBipartite(graph: number[][]): boolean {
405385

406386
```rust
407387
impl Solution {
408-
#[allow(dead_code)]
409388
pub fn is_bipartite(graph: Vec<Vec<i32>>) -> bool {
410389
let n = graph.len();
411-
let mut disjoint_set: Vec<usize> = vec![0; n];
412-
// Initialize the disjoint set
413-
for i in 0..n {
414-
disjoint_set[i] = i;
415-
}
390+
let mut p: Vec<usize> = (0..n).collect();
416391

417-
// Traverse the graph
418-
for i in 0..n {
419-
if graph[i].is_empty() {
420-
continue;
392+
fn find(x: usize, p: &mut Vec<usize>) -> usize {
393+
if p[x] != x {
394+
p[x] = find(p[x], p);
421395
}
422-
let first = graph[i][0] as usize;
423-
for v in &graph[i] {
424-
let v = *v as usize;
425-
let i_p = Self::find(i, &mut disjoint_set);
426-
let v_p = Self::find(v, &mut disjoint_set);
427-
if i_p == v_p {
396+
p[x]
397+
}
398+
399+
for a in 0..n {
400+
for &b in &graph[a] {
401+
let pa = find(a, &mut p);
402+
let pb = find(b as usize, &mut p);
403+
if pa == pb {
428404
return false;
429405
}
430-
// Otherwise, union the node
431-
Self::union(first, v, &mut disjoint_set);
406+
p[pb] = find(graph[a][0] as usize, &mut p);
432407
}
433408
}
434-
435409
true
436410
}
437-
438-
#[allow(dead_code)]
439-
fn find(x: usize, d_set: &mut Vec<usize>) -> usize {
440-
if d_set[x] != x {
441-
d_set[x] = Self::find(d_set[x], d_set);
442-
}
443-
d_set[x]
444-
}
445-
446-
#[allow(dead_code)]
447-
fn union(x: usize, y: usize, d_set: &mut Vec<usize>) {
448-
let p_x = Self::find(x, d_set);
449-
let p_y = Self::find(y, d_set);
450-
d_set[p_x] = p_y;
451-
}
452411
}
453412
```
454413

0 commit comments

Comments
 (0)