class Solution {
public int findCircleNum(int[][] M) {
boolean[] visited = new boolean[M.length];
int count = 0;
for (int i = 0; i < M.length; i++) {
if (!visited[i]) {
dfs(M, visited, i);
count++;
}
}
return count;
}
private void dfs(int[][] M, boolean[] visited, int i) {
for (int j = 0; j < M.length; j++) {
if(M[i][j] == 1 && !visited[j]) {
visited[j] = true;
dfs(M, visited, j);
}
}
}
}
class Solution {
public int findCircleNum(int[][] M) {
UF uf = new UF(M.length);
for (int i = 0; i < M.length; i++) {
for (int j = 0; j < i; j++) {
if (M[i][j] == 1) {
uf.union(i,j);
}
}
}
return uf.count();
}
class UF {
private int[] parents;
private int[] ranks;
private int count;
public UF(int capacity) {
parents = new int[capacity];
ranks = new int[capacity];
count = capacity;
for (int i = 0; i < capacity; i++) {
parents[i] = i;
ranks[i] = 1;
}
}
public void union(int v1, int v2) {
int p1 = find(v1);
int p2 = find(v2);
if (p1 == p2) return;
if (ranks[p1] < ranks[p2]) {
parents[p1] = p2;
} else if (ranks[p1] > ranks[p2]) {
parents[p2] = p1;
} else {
parents[p1] = p2;
ranks[p2]++;
}
count--;
}
public int find(int v) {
while (parents[v] != v) {
parents[v] = parents[parents[v]];
v = parents[v];
}
return v;
}
int count() {
return count;
}
}
}