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.node
For example:數組
Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return true.數據結構
Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], return false.app
Hint:this
Given n = 5 and edges = [[0, 1], [1, 2], [3, 4]], what should your return? Is this case a valid tree? Show More Hint Note: you can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges..net
時間 O(N^M) 空間 O(1)code
判斷輸入的邊是否能構成一個樹,咱們須要肯定兩件事:blog
這些邊是否構成環路,若是有環則不能構成樹接口
這些邊是否能將全部節點連通,若是有不能連通的節點則不能構成樹get
由於不須要知道具體的樹長什麼樣子,只要知道連通的關係,因此並查集相比深度優先搜索是更好的方法。咱們定義一個並查集的數據結構,並提供標準的四個接口:
union
將兩個節點放入一個集合中
find
找到該節點所屬的集合編號
areConnected
判斷兩個節點是不是一個集合
count
返回該並查集中有多少個獨立的集合
具體並查集的原理,參見這篇文章。簡單來說,就是先構建一個數組,節點0到節點n-1,剛開始都各自獨立的屬於本身的集合。這時集合的編號是節點號。而後,每次union操做時,咱們把整個並查集中,全部和第一個節點所屬集合號相同的節點的集合號,都改爲第二個節點的集合號。這樣就將一個集合的節點歸屬到同一個集合號下了。咱們遍歷一遍輸入,把全部邊加入咱們的並查集中,加的同時判斷是否有環路。最後若是並查集中只有一個集合,則說明能夠構建樹。
由於要判斷是否會產生環路,union方法要返回一個boolean,若是兩個節點原本就在一個集合中,就返回假,說明有環路
public class Solution { public boolean validTree(int n, int[][] edges) { UnionFind uf = new UnionFind(n); for(int i = 0; i < edges.length; i++){ // 若是兩個節點已經在同一集合中,說明新的邊將產生環路 if(!uf.union(edges[i][0], edges[i][1])){ return false; } } return uf.count() == 1; } public class UnionFind { int[] ids; int cnt; public UnionFind(int size){ this.ids = new int[size]; //初始化並查集,每一個節點對應本身的集合號 for(int i = 0; i < this.ids.length; i++){ this.ids[i] = i; } this.cnt = size; } public boolean union(int m, int n){ int src = find(m); int dst = find(n); //若是兩個節點不在同一集合中,將兩個集合合併爲一個 if(src != dst){ for(int i = 0; i < ids.length; i++){ if(ids[i] == src){ ids[i] = dst; } } // 合併完集合後,集合數減一 cnt--; return true; } else { return false; } } public int find(int m){ return ids[m]; } public boolean areConnected(int m, int n){ return find(m) == find(n); } public int count(){ return cnt; } } }