code
class Solution {
int[] par;
public int findCircleNum(int[][] isConnected) {
int len = isConnected.length;
par = new int[len];
for (int i = 0; i < len; i++) {
par[i] = i;
}
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {
if (isConnected[i][j] == 1){
union(i, j);
}
}
}
int count = 0;
for (int i = 0; i < len; i++) {
if (par[i] == i){
++count;
}
}
return count;
}
private int find(int x){
return x == par[x]? x: (par[x] = find(par[x]));
}
private void union(int i, int j){
int x = find(i);
int y = find(j);
par[x] = y;
}
}
下面附上一种基于压缩路路径和层数优化的并查集,上面的写法只用到了压缩路径,用三元运算符可以直接写成很简短的一句话
public class DsuDemo {
public static void main(String[] args) {
UnionFind test = new UnionFind(5);
System.out.println(test.isConnected(1, 3));
test.union(1, 3);
System.out.println(test.isConnected(1, 3));
test.union(3, 4);
System.out.println(test.isConnected(1, 4));
for (int i = 1; i <= 5; i++) {
System.out.println("parent of " + i + " is: " + test.getPar(i));
}
}
}
class UnionFind{
private int[] par;
private int[] rank;
UnionFind(int n){
par = new int[n + 1];
rank = new int[n + 1];
for (int i = 1; i <= n; i++) {
par[i] = i;
rank[i] = 1;
}
}
int getPar(int i){
return par[i];
}
int find(int x){
return x == par[x] ? x:(par[x] = find(par[x]));
}
boolean isConnected(int x, int y){
return find(x) == find(y);
}
void union(int x, int y){
int rootX = find(x);
int rootY = find(y);
if(rank[rootX] <= rank[rootY]){
par[rootX] = rootY;
}else{
par[rootY] = rootX;
}
if (rank[rootX] == rank[rootY]){
rank[rootY]++;
}
}
}