1. Description
Given a N*N matrix representing the relationship between every two students in the class.
Find the total number of friend circles in the class.
2. Solution
DFS / Union Find
dfs: Use dfs to traverse the matrix, and use an array to record whether students have been visited.
At every dfs process, choose a student who has never been visited, and visit all students who have direct or indirect relationship to his/her.
After the dfs process, a new friend circle formed, so add 1 to the answer.
Union Find:
Implement an array to represent the father of every points(students).
At the beginning, the father of one point is equal to the point value.
Traverse the matrix, if point i and point j are connected( student i and student j are direct friends),
calculate the ancestors of the two points.
If the two ancestors are not equal, set the father of point i's ancestor to father of point j's ancestor.
Return the number of different ancestors of all points.
3. Code
Union Find:
class Solution {
public:
int fa[210];
int findCircleNum(vector<vector<int>>& M) {
int n = M.size();
for(int i=0;i<n;i++)
fa[i]=i;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(M[i][j]==1){
int x = findfather(i);
int y = findfather(j);
if(x!=y)
fa[x]=y;
}
}
}
set<int>s;
for(int i=0;i<n;i++)
s.insert(findfather(i));
return s.size();
}
int findfather(int n){
if((fa[n])!=n) return findfather(fa[n]);
else return n;
}
};
DFS:
int findCircleNum(vector<vector<int>>& M) {
int n = M.size();
vector<bool>vis(n,false);
int ans = 0;
for(int i=0;i<n;i++){
if(!vis[i]){
dfs(M,vis,i,n);
ans++;
}
}
return ans;
}
void dfs(vector<vector<int>>& M,vector<bool>& vis,int start,int n){
vis[start]=true;
for(int i=0;i<n;i++){
if(M[start][i]==1 && !vis[i])
dfs(M,vis,i,n);
}
}