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; } } }