66
66
67
67
<!-- solution:start -->
68
68
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.
70
74
71
75
<!-- tabs:start -->
72
76
@@ -75,20 +79,17 @@ tags:
75
79
``` python
76
80
class Solution :
77
81
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)):
85
86
return False
86
87
return True
87
88
88
89
n = len (graph)
89
90
color = [0 ] * n
90
91
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 ):
92
93
return False
93
94
return True
94
95
```
@@ -112,14 +113,10 @@ class Solution {
112
113
return true ;
113
114
}
114
115
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))) {
123
120
return false ;
124
121
}
125
122
}
@@ -161,15 +158,11 @@ public:
161
158
func isBipartite (graph [][]int ) bool {
162
159
n := len (graph)
163
160
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)) {
173
166
return false
174
167
}
175
168
}
@@ -189,65 +182,47 @@ func isBipartite(graph [][]int) bool {
189
182
``` ts
190
183
function isBipartite(graph : number [][]): boolean {
191
184
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 ;
205
191
}
206
192
}
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 ;
212
198
}
213
199
}
214
- return valid ;
200
+ return true ;
215
201
}
216
202
```
217
203
218
204
#### Rust
219
205
220
206
``` rust
221
207
impl Solution {
222
- #[allow(dead_code)]
223
208
pub fn is_bipartite (graph : Vec <Vec <i32 >>) -> bool {
224
- let mut graph = graph ;
225
209
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
+ }
230
220
}
221
+ true
231
222
}
232
- true
233
- }
234
223
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 ) {
251
226
return false ;
252
227
}
253
228
}
@@ -262,7 +237,11 @@ impl Solution {
262
237
263
238
<!-- solution:start -->
264
239
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.
266
245
267
246
<!-- tabs:start -->
268
247
@@ -271,17 +250,18 @@ impl Solution {
271
250
``` python
272
251
class Solution :
273
252
def isBipartite (self , graph : List[List[int ]]) -> bool :
274
- def find (x ) :
253
+ def find (x : int ) -> int :
275
254
if p[x] != x:
276
255
p[x] = find(p[x])
277
256
return p[x]
278
257
279
258
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:
283
263
return False
284
- p[find(v) ] = find(g [0 ])
264
+ p[pb ] = find(bs [0 ])
285
265
return True
286
266
```
287
267
@@ -297,13 +277,13 @@ class Solution {
297
277
for (int i = 0 ; i < n; ++ i) {
298
278
p[i] = i;
299
279
}
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 ) {
304
284
return false ;
305
285
}
306
- p[find(v) ] = find(g [0 ]);
286
+ p[pb ] = find(graph[a] [0 ]);
307
287
}
308
288
}
309
289
return true ;
@@ -323,25 +303,26 @@ class Solution {
323
303
``` cpp
324
304
class Solution {
325
305
public:
326
- vector<int > p;
327
-
328
306
bool isBipartite(vector<vector<int >>& graph) {
329
307
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 ] );
337
323
}
338
324
}
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;
345
326
}
346
327
};
347
328
```
@@ -362,12 +343,13 @@ func isBipartite(graph [][]int) bool {
362
343
}
363
344
return p[x]
364
345
}
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 {
368
350
return false
369
351
}
370
- p[find(v) ] = find(g [0])
352
+ p[pb ] = find(bs [0])
371
353
}
372
354
}
373
355
return true
@@ -379,22 +361,20 @@ func isBipartite(graph [][]int) bool {
379
361
``` ts
380
362
function isBipartite(graph : number [][]): boolean {
381
363
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 ]) {
388
367
p [x ] = find (p [x ]);
389
368
}
390
369
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 ) {
395
375
return false ;
396
376
}
397
- p [find ( v ) ] = find (graph [u ][0 ]);
377
+ p [pb ] = find (graph [a ][0 ]);
398
378
}
399
379
}
400
380
return true ;
@@ -405,50 +385,29 @@ function isBipartite(graph: number[][]): boolean {
405
385
406
386
``` rust
407
387
impl Solution {
408
- #[allow(dead_code)]
409
388
pub fn is_bipartite (graph : Vec <Vec <i32 >>) -> bool {
410
389
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 ();
416
391
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 );
421
395
}
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 {
428
404
return false ;
429
405
}
430
- // Otherwise, union the node
431
- Self :: union (first , v , & mut disjoint_set );
406
+ p [pb ] = find (graph [a ][0 ] as usize , & mut p );
432
407
}
433
408
}
434
-
435
409
true
436
410
}
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
- }
452
411
}
453
412
```
454
413
0 commit comments