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)
我们可以根据这两点确定一个图是否为树。判断连通性可以使用BFS来实现。
public boolean validTree(int n, int[][] edges) {
if (n == 0) {
return false;
}
//判断有无回路
if (edges.length != n - 1) {
return false;
}
//判断连通性
Map<Integer, Set<Integer>> graph = initializeGraph(n, edges);
//bfs无脑创建queue
Queue<Integer> queue = new LinkedList<>();
//图的bfs与树不同在于,节点可能重复遍历,通过使用hash来确定
Set<Integer> hash = new HashSet<>();
queue.offer(0);
hash.add(0);
int visited = 0;
while (!queue.isEmpty()) {
int node = queue.poll();
visited++;
//遍历与node连通的每个节点
for (Integer neighbor : graph.get(node)) {
if (hash.contains(neighbor)) {
continue;
}
hash.add(neighbor);
queue.offer(neighbor);
}
}
return (visited == n);
}
//表示一个图
private Map<Integer,Set<Integer>> initializeGraph(int n, int[][] edges) {
Map<Integer, Set<Integer>> graph = new HashMap<>();
//为每个节点创建一个边集
for (int i = 0; i < n; i++) {
graph.put(i, new HashSet<Integer>());
}
for (int i = 0; i < edges.length; i++) {
//获取一条边的两个节点u、v
int u = edges[i][0];
int v = edges[i][1];
//将节点u、v对应的边加入它们的value
graph.get(u).add(v);
graph.get(v).add(u);
}
return graph;
}