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.
Example
Example 1:
Input: n = 5 edges = [[0, 1], [0, 2], [0, 3], [1, 4]]
Output: true.
Example 2:
Input: n = 5 edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]
Output: false.
Notice
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.
思路:是tree的条件:
1. 边是n-1
2. connected component is 1;
BFS,来判断以上两个条件,边是node-1,另外connect component is 1,如何判断connect component是1,就是遍历点的neibhor如果收集到最后是所有点,那么就是全部connect;
class Solution {
public boolean validTree(int n, int[][] edges) {
// 根据图论:以下三条满足任意两条即可
// 1.联通性
// 2.边数 = 节点数 - 1
// 3.是否有环
if(edges == null || edges.length != n - 1) {
return false;
}
HashMap<Integer, HashSet<Integer>> graph = buildGraph(n, edges);
Queue<Integer> queue = new LinkedList<>();
HashSet<Integer> visited = new HashSet<>();
queue.offer(0);
visited.add(0);
while(!queue.isEmpty()) {
Integer node = queue.poll();
for(Integer neighbor: graph.get(node)) {
if(!visited.contains(neighbor)) {
visited.add(neighbor);
queue.offer(neighbor);
}
}
}
return visited.size() == n;
}
private HashMap<Integer, HashSet<Integer>> buildGraph(int n, int[][] edges) {
HashMap<Integer, HashSet<Integer>> graph = new HashMap<>();
for(int i = 0; i < n; i++) {
graph.putIfAbsent(i, new HashSet<>());
}
for(int[] edge: edges) {
int a = edge[0];
int b = edge[1];
graph.get(a).add(b);
graph.get(b).add(a);
}
return graph;
}
}
思路2:用union find来做;
class Solution {
private class UnionFind {
private int[] father;
private int count;
public UnionFind(int n) {
this.father = new int[n + 1];
for(int i = 0; i <= n; i++) {
father[i] = i;
}
this.count = n;
}
public int find(int x) {
int j = x;
while(father[j] != j) {
j = father[j];
}
// path compression;
while(x != j) {
int fx = father[x];
father[x] = j;
x = fx;
}
return j;
}
public void union(int a, int b) {
int root_a = find(a);
int root_b = find(b);
if(root_a != root_b) {
father[root_a] = root_b;
this.count--;
}
}
public int getCount() {
return this.count;
}
}
public boolean validTree(int n, int[][] edges) {
UnionFind uf = new UnionFind(n);
for(int[] edge: edges) {
int a = edge[0];
int b = edge[1];
if(uf.find(a) == uf.find(b)) {
return false;
} else {
uf.union(a, b);
}
}
return uf.getCount() == 1;
}
}