解法一:采用并查集的思想,将每一个学生附上相应的标签,若M(i,j)==1,那么按照“靠左”原则,flag[i]==flag[j]==i;
class Solution {
public:
int get(vector<int> flag, int item)
{
if(flag[item]==item)
return item;
else
{
flag[item]=get(flag,flag[item]); //更新节点value为最高祖先
return flag[item];
}
}
void merge(vector<int> &flag,int left,int right)
{
int x=get(flag,left);
int y=get(flag,right); //获取当前节点的祖先
if(x!=y)
flag[y]=x; //祖先不同,“靠左”原则,更新祖先
}
int findCircleNum(vector<vector<int>>& M)
{
vector<int> flag(M[0].size());
for(int i = 0;i<M[0].size();i++)
flag[i] = i; //初始化各节点的祖先
for(int i = 0;i<M[0].size();i++)
{
for (int j = i+1;j<M[0].size();j++)
{
if(M[i][j]==1)
merge(flag,i,j);
}
}
int ans=0;
for(int i=0;i<flag.size();i++)
if(flag[i]==i)
ans++;
return ans;
}
};
解法二:采用DFS的思想,深度优先搜索关联矩阵,计算搜索路径的数目
class Solution {
public:
void dfs(vector<vector<int>>& M,vector<bool>& visit,int item)
{
visit[item]=1; //开始当前节点的遍历,改为已遍历标记
for(int i=0;i<M.size();i++)
{
if(visit[i]||!M[item][i]) //关联节点已被遍历,或者节点不关联
continue;
dfs(M,visit,i); //开始遍历关联节点
}
}
int findCircleNum(vector<vector<int>>& M)
{
int ans=0;
vector<bool> visit(M.size());
for(int i=0;i<M.size();i++)
{
if(!visit[i]) //当前节点未被遍历
{
dfs(M,visit,i);
ans++;
}
}
return ans;
}
};