http://www.lintcode.com/zh-cn/problem/graph-valid-tree/#
解法一:并查集
id[i]保存当前结点i的根节点,因为如果有公共根节点,那么再相连就一定成环,每次find的时候将不是root的置为root
public class Solution {
/**
* @param n an integer
* @param edges a list of undirected edges
* @return true if it's a valid tree, or false
*/
// id保存当前结点的根节点,因为如果有公共根节点,那么再相连就一定成环
int[] id;
int count;
public boolean validTree(int n, int[][] edges) {
// Write your code here
count = n;
id = new int[n];
for (int i = 0; i < n; i++) {
id[i] = i;
}
for (int i = 0; i < edges.length; i++) {
int p = edges[i][0];
int q = edges[i][1];
if (find(p) == find(q)) {
return false;
} else {
union(p, q);
}
}
return count == 1;
}
private int find(int i) {
int root = i;
while (root != id[root]) {
root = id[root];
}
while (i != root) {
int tmp = id[i];
id[i] = root;
i = tmp;
}
return root;
}
private void union(int i, int j) {
int p = find(i);
int q = find(j);
if (p != q) {
id[p] = q;
count--;
}
}
}
解法二:DFS用List<List<Integer>>保存连接关系,visited保存已访问位置,如果将要访问的在已访问的之中,那么就有环。
public class Solution {
/**
* @param n an integer
* @param edges a list of undirected edges
* @return true if it's a valid tree, or false
*/
public boolean validTree(int n, int[][] edges) {
// Write your code here
HashSet<Integer> visited = new HashSet<>();
List<List<Integer>> list = new LinkedList<>();
for (int i = 0; i < n; i++) {
list.add(new ArrayList<Integer>());
}
for (int i = 0; i < edges.length; i++) {
list.get(edges[i][0]).add(edges[i][1]);
list.get(edges[i][1]).add(edges[i][0]);
}
if (cycle(-1, 0, list, visited)) {
return false;
}
return visited.size() == n;
}
private boolean cycle(Integer pre, Integer cur, List<List<Integer>> list, HashSet<Integer> visit) {
visit.add(cur);
for (Integer succ : list.get(cur)) {
if (!succ.equals(pre)) {
if (visit.contains(succ)) {
return true;
} else {
if (cycle(cur, succ, list, visit)) {
return true;
}
}
}
}
return false;
}
}