http://www.lintcode.com/en/problem/graph-valid-tree/
题目:判断图是否是树 n 表示 0 ~ n - 1个点, edges表示边,如【0,1】表示连接0和1的边(无重复边)
解答:需要满足两个条件:
(1)边的个数 = n - 1;
(2) 所有的边可以将全部点连通;
将每个点作为key值,与其相连的点的集合作为value创建一个HashMap。创建一个HashSet用来存放树中所有的节点。创建一个queue并将0放入队列中,若队列不为空重复以下操作:
依次遍历当前出队列元素的HashMap的value集合,若存在HashSet里没有的元素,将其加入HashSe中并放入队列。
若循环结束后的HashSet的大小 = n 则表示该图是树。(此方法也可以应用于存在重复边的情况)
第一次犯错:忘记考虑 n = 0 的情况;
第二次犯错:使用hashset判断所有的点是否都在边中有出现,但是有n个不同点出现,也未必保证将所有点连通;
代码:
public boolean validTree(int n, int[][] edges) {
// Write your code here
if (n == 0) {
return false;
}
int numEdge = edges.length;
if (numEdge != n - 1) {
return false;
}
Set<Integer> set = new HashSet<>();
Map<Integer, Set<Integer>> map = new HashMap<>();
Queue<Integer> queue = new LinkedList<>();
set.add(0);
queue.offer(0);
for (int i = 0; i < n; i++) {
map.put(i, new HashSet<Integer>());
}
for (int i = 0; i < numEdge; i++) {
int a = edges[i][0];
int b = edges[i][1];
map.get(a).add(b);
map.get(b).add(a);
}
while (!queue.isEmpty()) {
int newNode = queue.poll();
for (int node : map.get(newNode)) {
if (set.add(node)) {
queue.offer(node);
}
}
}
if (set.size() != n) {
return false;
}
return true;
}