class Solution { class UF { private int count; private int parent[]; //它的父节点 private int size[]; //以自己为根节点的树有多少节点 public UF(int n) { this.count = n; parent = new int[n]; size = new int[n]; //初始化的时候自己的父节点指向自己 for (int i = 0; i < n; i++) { parent[i] = i; size[i] = 1; } } //找到x的根节点 private int find(int x) { while (x != parent[x]) { //路径压缩,画个图就明白了。就是和自己的父亲做兄弟。 parent[x] = parent[parent[x]]; x = parent[x]; } return x; } //连接 public void union(int p, int q) { //找到各自的根节点。 int rootP = find(p); //你看,每次find的时候都进行了路径压缩。 int rootQ = find(q); if (rootP == rootQ) return; //把小的树接到大的树上面 if (size[rootQ] > size[rootP]) { parent[rootP] = rootQ; size[rootQ] += size[rootP]; } else { parent[rootQ] = rootP; size[rootP] += size[rootQ]; } count--; } public boolean connect(int p, int q) { return find(p) == find(q); } public int count() { return count; } } public int findCircleNum(int[][] M) { int N = M.length; UF uf = new UF(N); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (M[i][j] == 1) { uf.union(i, j); } } } return uf.count(); } }
原文:https://www.cnblogs.com/CPJ31415/p/14135090.html