22
33/**
44 * Created by dingjikerbo on 17/1/2.
5+ * <p>
6+ * 判断无向图是否带环,可采用UF, DFS, BFS。
7+ * UF实现简单,性能很好
8+ * <p>
9+ * 题目中已声明不会有重复的边,类似[0,1]和[1,0]认为是重复的,也不会同时存在
510 */
611/**
712 * 判断无向图是否带环,可采用UF, DFS, BFS。
1217 */
1318
1419import java .util .ArrayList ;
20+ import java .util .HashSet ;
21+ import java .util .LinkedList ;
1522import java .util .List ;
23+ import java .util .Queue ;
24+ import java .util .Set ;
1625
1726/**
1827 * 这题就是给了一堆边,看这些边构成的无向图会不会有环,另外这些边是不是都连在一起的
@@ -59,7 +68,7 @@ public boolean validTree(int n, int[][] edges) {
5968 }
6069
6170 int find (int nums [], int i ) {
62- for (; nums [i ] != i ; i = nums [i ]);
71+ for (; nums [i ] != i ; i = nums [i ]) ;
6372 return i ;
6473 }
6574
@@ -77,22 +86,11 @@ public boolean validTree2(int n, int[][] edges) {
7786 graph [edges [i ][0 ]].add (edges [i ][1 ]);
7887 graph [edges [i ][1 ]].add (edges [i ][0 ]);
7988 }
80- boolean [] visited = new boolean [n ];
81-
82- /**
83- * 这里从任意一点开始DFS都可以
84- */
89+ Set <Integer > visited = new HashSet <>();
8590 if (!dfs (graph , visited , 0 , -1 )) {
8691 return false ;
8792 }
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 ;
9694 }
9795
9896 /**
@@ -101,22 +99,51 @@ public boolean validTree2(int n, int[][] edges) {
10199 * @parent 为了避免逆向遍历,因为parent肯定是访问过的,所以为了避免看作重复访问,这里排除了一下
102100 * @return 是否无环
103101 */
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 )) {
116108 return false ;
117109 }
118110 }
119-
120111 return true ;
121112 }
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+ }
122149}
0 commit comments