leetcode 261-Graph Valid Tree(medium)(BFS, DFS, Union find)
Given n
nodes labeled from 0
to n-1
and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.
這道題主要就是判斷1.是否有環路 2. 是否是連通圖
可以用DFS, BFS 和 Union find,union find最合適。
對於DFS和BFS,首先都是建立adjacent list,把edges連接的所有情況加入鄰接鏈表,註意需要對稱加入,對於[a,b],要對a加入b,對b加入a。都可以用visited來記錄是否遍歷過。
1. BFS
bfs基本都是用queue實現,首先加入第一個點,每次poll出一個點,對其鄰接鏈表遍歷,入隊,註意要將該點從其遍歷到的鄰接鏈表的點的鄰接鏈表中刪去,保證一條邊不會來回走兩次(為什麽前面要對稱加入而這裏又要刪去一邊,因為不知道點之間聯通的情況是怎麽樣的,在進行遍歷的時候可能是從a->b的方向也可能相反,如果只加一個,在連通圖遍歷的時候本來連著的邊會斷掉)。用count記錄連入連通圖的點的個數,最後和n比。
再次提醒,對於list之類get到的點,都是object,不是int,在賦值給int時要(int),在用remove時,註意remove掉的是object,不能是int,remove(int index),remove(object ob),這兩種要區分開,這裏是要remove掉這個對象,所以要加(Integer)。
class Solution { public boolean validTree(int n, int[][] edges) { if(n==0) return false; List[] list=new List[n]; for(int i=0;i<n;i++){ list[i]=new ArrayList<Integer>(); } for(int[] pair:edges){ list[pair[0]].add(pair[1]); list[pair[1]].add(pair[0]); } Queue<Integer> queue=new LinkedList<>(); queue.offer(0); boolean[] visited=new boolean[n]; int count=1; while(!queue.isEmpty()){ int a=queue.poll(); if(visited[a]) return false; visited[a]=true; for(int i=0;i<list[a].size();i++){ int m=(int)list[a].get(i);//註意要轉int queue.offer(m); count++; list[m].remove((Integer)a);//註意要加(Integer),要不然是被認為是index,刪除 } } return count==n; } }
2.DFS
dfs中需要記錄pre,來避免a->b->a這樣的遍歷,從而被當成是環路。
class Solution { public boolean validTree(int n, int[][] edges) { if(n==0) return false; List[] list=new List[n]; for(int i=0;i<n;i++){ list[i]=new ArrayList<Integer>(); } for(int[] pair:edges){ list[pair[0]].add(pair[1]); list[pair[1]].add(pair[0]); } boolean[] visited=new boolean[n]; if(dfs(list, visited, 0,-1)) return false; for(int i=0;i<n;i++){ if(!visited[i]) return false; } return true; } public boolean dfs(List[] list, boolean[] visited, int id, int pre){ if(visited[id]) return true; visited[id]=true; for(int i=0;i<list[id].size();i++){ if(pre==(int)list[id].get(i)) continue; if(dfs(list, visited, (int)list[id].get(i), id)) return true; } return false; } }
3. Union Find
用count記錄連通圖的個數,每並一次說明少一個分裂塊,如果最後變為1,說明全部連通。
class Solution { public boolean validTree(int n, int[][] edges) { int[] connect=new int[n]; if(edges.length!=n-1) return false; for(int i=0;i<n;i++){ connect[i]=i; } int count=n; for(int i=0;i<edges.length;i++){ int a=findroot(connect,edges[i][0]); int b=findroot(connect,edges[i][1]); if(a==b) return false; count--; connect[b]=a; } return count==1; } public int findroot(int[] connect, int id){ while(connect[id]!=id) id=connect[id]; return id; } }
leetcode 261-Graph Valid Tree(medium)(BFS, DFS, Union find)