在图论的算法题中,虽然最常用的算法是DFS和BFS,但是在求连通分量数量的时候,借助并查集这一数据结构是是十分简单的,以leetcode-547,省份数量 这道题举例。
public int findCircleNum(int[][] isConnected) {
int size = isConnected.length;
UnionFind unionFind = new UnionFind(size);
for (int i = 0; i < size; i++) {
for (int j = i + 1; j < size; j++) {
if (isConnected[i][j] == 1) {
// 如果两省份相连,直接使用并查集联合
unionFind.unionElement(i, j);
}
}
}
int res = 0;
for (int i = 0; i < size; i++) {
if (unionFind.find(i) == i) {
res++;
}
}
return res;
}
/**
* 并查集的数据结构
*/
class UnionFind {
int[] parent;
int[] rank;
public UnionFind(int size) {
this.parent = new int[size];
this.rank = new int[size];
for (int i = 0; i < size; i++) {
parent[i] = i;
rank[i] = 1;
}
}
public boolean isConnected(int p, int q) {
return find(p) == find(q);
}
private int find(int p) {
while (p != parent[p]) {
parent[p] = parent[parent[p]];
p = parent[p];
}
return p;
}
public void unionElement(int p, int q) {
int proot = find(p);
int qroot = find(q);
if (rank[proot] < rank[qroot]) {
parent[proot] = qroot;
} else if (rank[proot] > rank[qroot]) {
parent[qroot] = proot;
} else {
parent[proot] = qroot;
rank[qroot] += 1;
}
}
}