class Solution {
public boolean validTree(int n, int[][] edges) {
UF uf = new UF(n);
for (int i = 0; i < edges.length; i++) {
if (uf.connected(edges[i][0],edges[i][1])) return false; // A cycle
uf.union(edges[i][0],edges[i][1]);
}
return edges.length == n - 1;
}
}
class UF {
int[] father;
int count;
// All other parts are the same.
// The difference is how to initialize UF.
public UF(int n) {
father = new int[n];
count = n;
for (int i = 0; i < n; i++) {
father[i] = i;
}
}
public void union(int p, int q) {
int pFather = find(p);
int qFather = find(q);
if (pFather != qFather) {
father[pFather] = qFather;
count--;
}
}
public int find(int p) {
while (p != father[p]) p = father[p];
return p;
}
public int count() {
return count;
}
public boolean connected(int p, int q) {
return find(p) == find (q);
}
}
Optimized: path compression, union by size weight.
class UF {
int[] father;
int[] size;
int count;
// All other parts are the same.
// The difference is how to initialize UF.
public UF(int n) {
count = n;
father = new int[n];
for (int i = 0; i < n; i++) father[i] = i;
size = new int[n];
for (int i = 0; i < n; i++) size[i] = 1;
}
public void union(int p, int q) {
int pFather = find(p);
int qFather = find(q);
if (pFather == qFather) return;
if (size[p] > size[q]) {
father[qFather] = pFather;
} else {
father[pFather] = qFather;
}
count--;
}
// Path compression
public int find(int p) {
if (p != father[p]) {
father[p] = find(father[p]);
}
return father[p];
}
public int count() {
return count;
}
public boolean connected(int p, int q) {
return find(p) == find (q);
}
}
Use map to represent fathers.
class UnionFind {
Map<String, String> fathers = new HashMap<>();
void connect(String s1, String s2) {
fathers.putIfAbsent(s1, s1);
fathers.putIfAbsent(s2, s2);
String f1 = find(s1);
String f2 = find(s2);
if (!f1.equals(f2)) fathers.put(f1, f2);
}
String find(String s) {
if (!fathers.get(s).equals(s)) {
fathers.put(s, find(fathers.get(s)));
}
return fathers.get(s);
}
}
Union the edges. If two vertex are already connected, then current edge will form a cycle.
Node A, B connected: there is a path from A to B.