547. 朋友圈
- 朋友圈
難度中等238
班上有 N 名學生。其中有些人是朋友,有些則不是。他們的友誼具有是傳遞性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那麼我們可以認爲
A 也是 C 的朋友。所謂的朋友圈,是指所有朋友的集合。給定一個 N * N 的矩陣 M,表示班級中學生之間的朋友關係。如果Mi = 1,表示已知第 i 個和 j
個學生互爲朋友關係,否則爲不知道。你必須輸出所有學生中的已知的朋友圈總數。示例 1:
輸入: [[1,1,0], [1,1,0], [0,0,1]] 輸出: 2 說明:已知學生0和學生1互爲朋友,他們在一個朋友圈。 第2個學生自己在一個朋友圈。所以返回2。
1.dfs
private void dfs(int [][] M , int [] visited,int i){
for(int j=0;j<M.length;j++){
if(M[i][j]==1&&visited[j]==0){
visited[j] = 1;
dfs(M,visited,j);
}
}
}
public int findCircleNum(int[][] M) {
int [] visited = new int [M.length];
int count = 0;
for(int i=0;i<M.length;i++){
if(visited[i] == 0){
dfs(M,visited,i);
count++;
}
}
return count;
}
2.並查集
public int findCircleNum(int[][] M) {
int n = M.length;
UnionFind uf = new UnionFind(n);
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
if (M[i][j] == 1) uf.union(i, j);
}
}
return uf.count;
}
}
class UnionFind {
public int count = 0;
private int[] parent;
public UnionFind(int n) {
count = n;
parent = new int[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
}
}
public int find(int p) {
while (p != parent[p]) {
parent[p] = parent[parent[p]];
p = parent[p];
}
return p;
}
public void union(int p, int q) {
int rootP = find(p);
int rootQ = find(q);
if (rootP == rootQ)
return;
parent[rootP] = rootQ;
count--;
}
}