题目地址:
https://www.lintcode.com/problem/connecting-graph-iii/description
给定 n n n个顶点标号为 1 ∼ n 1\sim n 1∼n,再给定若干次操作,每次操作会将两个顶点用无向边连起来。要求动态返回连通分量个数。
并查集天然适合这个问题。代码如下:
public class ConnectingGraph3 {
class UnionFind {
private int[] parent, rank;
// group记录有多少个等价类
int group;
public UnionFind(int n) {
parent = new int[n];
rank = new int[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
rank[i] = 1;
}
group = n;
}
public int find(int p) {
if (p != parent[p]) {
parent[p] = find(parent[p]);
}
return parent[p];
}
public void union(int p, int q) {
int pRoot = find(p), qRoot = find(q);
if (pRoot == qRoot) {
return;
}
if (rank[pRoot] < rank[qRoot]) {
parent[pRoot] = qRoot;
} else if (rank[pRoot] > rank[qRoot]) {
parent[qRoot] = pRoot;
} else {
parent[pRoot] = qRoot;
rank[qRoot]++;
}
group--;
}
}
private UnionFind uf;
/**
* @param a: An integer
* @param b: An integer
* @return: nothing
*/
public ConnectingGraph3(int n) {
// initialize your data structure here.
uf = new UnionFind(n);
}
public void connect(int a, int b) {
// write your code here
uf.union(a - 1, b - 1);
}
/**
* @return: An integer
*/
public int query() {
// write your code here
return uf.group;
}
}
connect的时间复杂度 O ( log ∗ n ) O(\log^*n) O(log∗n),空间 O ( n ) O(n) O(n)( n n n为顶点个数)。