最近阅读到一篇关于并查集的博客文章,自己也研究一下。
并查集算法的主要概念
初始化(Init):初始化定义,将每个对象的父节点指向自己;
查询(Find):查询两个元素是否在同一个集合中;
合并(Union):把两个不相交的集合合并为一个集合。
以LeetCode中547. 省份数量为例解释算法。
题目中给定一个图的邻接矩阵isConnected[ ][ ],矩阵中0表示不相连,1表示相连;需要输出集合总数。
class Solution {
public int findCircleNum(int[][] isConnected) {
int n = isConnected.length;
// 初始化
UnionFind uf = new UnionFind(n);
for(int i = 0;i<isConnected.length;i++){
for(int j = 0;j<isConnected[0].length;j++){
// 查找每条边,如果两端之间连接正常
if(isConnected[i][j] == 1){
// 合并
uf.union(i,j);
}
}
}
return uf.size;
}
}
class UnionFind{
int size;
int[] roots;
// 初始化
public UnionFind(int n){
roots = new int[n];
for(int i = 0;i<n;i++){
roots[i] = i;
}
size = n;
}
// 查
public int find(int i){
if(roots[i] == i){
return i;
}
roots[i] = find(roots[i]);
return roots[i];
}
// 并
public void union(int i,int j){
int proot = find(i);
int qroot = find(j);
if(qroot!=proot){
roots[proot] = qroot;
size--;
}
}
}