刷
June-23-2019
先用UF做了一下,这个不容易想到。valid tree说明
UF最终只有一个group
每次加的2个node都不能发现它已经在树里了。
比如[1,2][3,4]第一个条件不满足
[1,2][2,3][1,3]第二个条件不满足
然后做就行了。其实用n + 1 == edges.length就足够判断第一个条件了。。
find的时候,先压缩树,父指到爷;然后再find第二次,都指向最终root(这2个其实冲突了,相当于第二次指向root只指了其中的一半)
UF的用size来平衡树,永远小的往大的上面连。然而其实有上面的过程,balance不是很有必要,毕竟find()的时间按理说是1.锻炼下还是写了,否则代码能简单很多
class Solution {
public class UF {
Map<Integer, Integer> parent;
Map<Integer, Integer> height;
int group = 0;
public UF(int n) {
parent = new HashMap<>();
height = new HashMap<>();
for (int i = 0; i < n; i ++) {
parent.put(i, i);
height.put(i, 1);
}
group = n;
}
public Integer find(Integer i) {
if (i == null || !parent.containsKey(i)) return null;
Integer root = i;
while (!root.equals(parent.get(root))) {
parent.put(root, parent.get(parent.get(root)));
root = parent.get(root);
}
while (!i.equals(root)) {
Integer temp = parent.get(i);
parent.put(i, root);
i = temp;
}
return root;
}
public void union(Integer a, Integer b) {
Integer rootA = find(a);
Integer rootB = find(b);
if (rootA == null || rootB == null) return;
if (rootA.equals(rootB)) return;
Integer heightA = height.get(rootA);
Integer heightB = height.get(rootB);
if (heightA > heightB) {
parent.put(rootB, rootA);
height.put(heightA, heightA + heightB);
} else {
parent.put(rootA, rootB);
height.put(heightB, heightA + heightB);
}
group --;
}
}
public boolean validTree(int n, int[][] edges) {
UF uf = new UF(n);
for (int[] edge : edges) {
Integer rootA = uf.find(edge[0]);
Integer rootB = uf.find(edge[1]);
if (rootA.equals(rootB)) {
return false;
} else {
uf.union(rootA, rootB);
}
}
return uf.group == 1;
}
}
然后什么都不考虑的简单版UF
class Solution {
public int find(int i, int[] nums) {
while (i != nums[i]) {
i = nums[i];
}
return i;
}
public void union(Integer a, Integer b, int[] nums) {
nums[a] = nums[b];
}
public boolean validTree(int n, int[][] edges) {
int[] node = new int[n];
for (int i = 0; i < n; i ++) {
node[i] = i;
}
for (int[] edge : edges) {
int a = find(edge[0], node);
int b = find(edge[1], node);
if (a == b) {
return false;
} else {
union(a, b, node);
}
}
return edges.length == n - 1;
}
}