2
2
3
3
/**
4
4
* Created by dingjikerbo on 17/1/2.
5
+ * <p>
6
+ * 判断无向图是否带环,可采用UF, DFS, BFS。
7
+ * UF实现简单,性能很好
8
+ * <p>
9
+ * 题目中已声明不会有重复的边,类似[0,1]和[1,0]认为是重复的,也不会同时存在
5
10
*/
6
11
/**
7
12
* 判断无向图是否带环,可采用UF, DFS, BFS。
12
17
*/
13
18
14
19
import java .util .ArrayList ;
20
+ import java .util .HashSet ;
21
+ import java .util .LinkedList ;
15
22
import java .util .List ;
23
+ import java .util .Queue ;
24
+ import java .util .Set ;
16
25
17
26
/**
18
27
* 这题就是给了一堆边,看这些边构成的无向图会不会有环,另外这些边是不是都连在一起的
@@ -59,7 +68,7 @@ public boolean validTree(int n, int[][] edges) {
59
68
}
60
69
61
70
int find (int nums [], int i ) {
62
- for (; nums [i ] != i ; i = nums [i ]);
71
+ for (; nums [i ] != i ; i = nums [i ]) ;
63
72
return i ;
64
73
}
65
74
@@ -77,22 +86,11 @@ public boolean validTree2(int n, int[][] edges) {
77
86
graph [edges [i ][0 ]].add (edges [i ][1 ]);
78
87
graph [edges [i ][1 ]].add (edges [i ][0 ]);
79
88
}
80
- boolean [] visited = new boolean [n ];
81
-
82
- /**
83
- * 这里从任意一点开始DFS都可以
84
- */
89
+ Set <Integer > visited = new HashSet <>();
85
90
if (!dfs (graph , visited , 0 , -1 )) {
86
91
return false ;
87
92
}
88
-
89
- for (int i = 0 ; i < n ; i ++) {
90
- if (!visited [i ]) {
91
- return false ;
92
- }
93
- }
94
-
95
- return true ;
93
+ return visited .size () == n ;
96
94
}
97
95
98
96
/**
@@ -101,22 +99,51 @@ public boolean validTree2(int n, int[][] edges) {
101
99
* @parent 为了避免逆向遍历,因为parent肯定是访问过的,所以为了避免看作重复访问,这里排除了一下
102
100
* @return 是否无环
103
101
*/
104
- private boolean dfs (List <Integer >[] graph , boolean [] visited , int start , int parent ) {
105
- visited [start ] = true ;
106
-
107
- for (int i = 0 ; i < graph [start ].size (); i ++) {
108
- int to = graph [start ].get (i );
109
- if (to == parent ) {
110
- continue ;
111
- }
112
- if (visited [to ]) {
113
- return false ;
114
- }
115
- if (!dfs (graph , visited , to , start )) {
102
+ private boolean dfs (List <Integer >[] graph , Set <Integer > visited , int start , int parent ) {
103
+ if (!visited .add (start )) {
104
+ return false ;
105
+ }
106
+ for (Integer to : graph [start ]) {
107
+ if (to != parent && !dfs (graph , visited , to , start )) {
116
108
return false ;
117
109
}
118
110
}
119
-
120
111
return true ;
121
112
}
113
+
114
+ /**
115
+ * BFS
116
+ */
117
+ public boolean validTree3 (int n , int [][] edges ) {
118
+ List <Integer >[] graph = new ArrayList [n ];
119
+ for (int i = 0 ; i < n ; i ++) {
120
+ graph [i ] = new ArrayList <>();
121
+ }
122
+ for (int i = 0 ; i < edges .length ; i ++) {
123
+ graph [edges [i ][0 ]].add (edges [i ][1 ]);
124
+ graph [edges [i ][1 ]].add (edges [i ][0 ]);
125
+ }
126
+ Set <Integer > visited = new HashSet <>();
127
+ Queue <Integer > queue = new LinkedList <>();
128
+
129
+ queue .offer (0 );
130
+ visited .add (0 );
131
+
132
+ while (!queue .isEmpty ()) {
133
+ int k = queue .poll ();
134
+
135
+ for (Integer near : graph [k ]) {
136
+ if (!visited .add (near )) {
137
+ return false ;
138
+ }
139
+ queue .offer (near );
140
+ /**
141
+ * 这个remove别掉了,且必须是Integer.valueOf,
142
+ * 否则被当成index了
143
+ */
144
+ graph [near ].remove (Integer .valueOf (k ));
145
+ }
146
+ }
147
+ return visited .size () == n ;
148
+ }
122
149
}
0 commit comments