547.省份数量
思路一:UnionFind (并查集)
我们使用UnionFind将不同联通的合并为一个Class。
自己手写并查集
class Solution {
public int findCircleNum(int[][] isConnected) {
int n = isConnected.length;
UF uf = new UF(n);
// 因为是对称的,所以j只需要从i+1开始即可
for(int i=0;i<n;i++)
for(int j=i;j<n;j++)
if(isConnected[i][j]==1)
uf.union(i,j);
//System.out.println(uf.count());
return uf.count();
}
}
//自己实现并查集
class UF{
int[] elments;
int[] sz; //标记当前节点对应的根节点的树的高度
// 初始化
public UF(int size){
int[] tmp = new int[size];
int[] tmp2 = new int[size];
for(int i=0;i<size;i++)
tmp[i]=i;
this.elments=tmp;
this.sz=tmp2;
}
// Find with compression
public int find(int i){
if(elments[i]==i)
return i;
else{
elments[i] = find(elments[i]);
}
return elments[i];
}
// Union
public void union(int i,int j){
int parenti = find(i);
int parentj = find(j);
if(sz[i]==sz[j]){
elments[parentj]=parenti;
sz[parenti]++;
}
else if(sz[i]>sz[j]){
elments[parentj]=parenti;
}
else{
elments[parenti]=parentj;
}
}
// 返回class数量
public int count(){
HashSet<Integer> tmp = new HashSet<>();
for(int i=0;i<elments.length;i++)
tmp.add(find(elments[i]));
return tmp.size();
}
}
改进
这里其实我们注意到返回class的数量实际上就是检查我们有多少个“树”,即根节点(elements[i]=i)的个数,所以可以将最后一个函数改为:
public int count(){
int res=0;
for(int i=0;i<elments.length;i++)
if(elments[i]==i)
res++;
return res;
}
这样就不用查重了,因此也快了很多。
思路二:BFS
[待做]
思路三:DFS
[待做]