leetcode 547朋友圈

方法一:染色法

类似于岛屿的个数也可以用染色法:通过深度优先搜索来做

使用一个数组来表示当前朋友a是否已经包含到已经遍历的朋友圈中,遍历所有的朋友,如果当前朋友没有在已经访问的朋友圈中,即visited==false,那么cnt++;并将该朋友所有相关的朋友使用dfs全部标记为visited=true;

当遍历完成时,cnt即为结果;并且不改变原数组,时间复杂度O(n^2),即遍历M的每个元素;空间复杂度为O(n);

C++代码:

class Solution {
public:
    int findCircleNum(vector<vector<int>>& M) {
        int m=M.size();
        if(m==0) return 0;
        int cnt=0;
        vector<bool>visited(m,false);
        for(int i=0;i<m;i++){
            if(!visited[i]){
                dfs(M,visited,i);
                cnt++;
            }
        }
        return cnt;
    }
    void dfs(vector<vector<int>>&M,vector<bool>&visited,int i){
        int m=M.size();
        for(int j=0;j<m;j++){
            if(M[i][j]==1 && !visited[j]){
                visited[j]=true;
                dfs(M,visited,j);
            }
        }
    }
};

方法二:并查集

//使用并查集,基本思想是假设所有人都独立,初始化朋友圈为n个,如果两个人相关那么n--,将所有人遍历可得到朋友圈个数;
class Solution {
public:
    int findCircleNum(vector<vector<int>>& M) {
        int n=M.size();
        if(n==0) return 0;
        int groups=n;
        vector<int>leads(n,0);
        for(int i=0;i<n;i++) leads[i]=i;
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                if(M[i][j]==1){
                int lead1=find(i,leads);
                int lead2=find(j,leads);
                if(lead1!=lead2){
                    groups--;leads[lead1]=lead2;
                }
                }
            }
        }
        return groups;
    }
private:
    int find(int x,vector<int>&parents){
        if(x==parents[x])
            return x;
        else
            return find(parents[x],parents);
    }
};
原文地址:https://www.cnblogs.com/joelwang/p/10876557.html