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
7680class 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:
161158func 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
190183function 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
221207impl 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
272251class 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
324304class Solution {
325305public:
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
380362function 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
407387impl 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