版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Somnus_k/article/details/82388130
并查集介绍参考:
https://juejin.im/entry/5922593d44d904006cd20175
http://dongxicheng.org/structure/union-find-set/
实现代码:
class Solution {
public int findCircleNum(int[][] num) {
// 最初朋友圈的个数
int count = num.length;
int father[] = new int[num.length];
// 存储每个节点的秩
int rank[] = new int[num.length];
// 初始化父节点,father[x]=y表示x的父节点是y
for (int i = 0; i < father.length; i++) {
father[i] = i;
}
for (int i = 0; i < father.length; i++) {
for (int j = 0; j <= i; j++) {
if (num[i][j] == 1)
count = Union(father, rank, i, j, count);
}
}
return count;
}
int find(int[] father, int x) {
if (x != father[x]) {
father[x] = find(father, father[x]); // 这个回溯时的压缩路径是精华
}
return father[x];
}
int Union(int[] father, int[] rank, int x, int y, int count) {
x = find(father, x);
y = find(father, y);
if (x == y)
return count;
if (rank[x] > rank[y]) {
father[y] = x;
} else {
if (rank[x] == rank[y]) {
rank[y]++;
}
father[x] = y;
}
// 每次朋友圈合并,将朋友圈个数减1
count--;
return count;
}
}
测试用例:{ { 1, 1, 0 }, { 1, 1, 0 }, { 0, 0, 1 } }
结果:2