[LeetCode] 547. Friend Circles 朋友圈

      本题可以套用和 [LeetCode] 200. Number of Islands 岛屿的数量 与 [LeetCode 695] Max Area of Island 岛的最大面积一样的dfs模版,不同的是DFS的遍历路径不同,本题

采用的是类似十字遍历方式,具体见如下代码。

 1 /*
 2  * @Descripttion: 
 3  * @version: 
 4  * @Author: wangxf
 5  * @Date: 2019-12-20 15:21:49
 6  * @LastEditors: Do not edit
 7  * @LastEditTime: 2020-04-12 23:25:24
 8  */
 9 /*
10  * @lc app=leetcode.cn id=547 lang=cpp
11  *
12  * [547] 朋友圈
13  */
14 
15 // @lc code=start
16 #include<bits/stdc++.h>
17 using namespace std;
18 class Solution {
19 public:
20     int findCircleNum(vector<vector<int>>& M)
21     {
22         int res = 0;
23         if(M.empty()||M.size()<=0) return 0;
24         for (size_t i = 0; i < M.size(); i++)
25             for (size_t j = 0; j < M[0].size(); j++)
26             {
27                 /*
28                 if(i==j)
29                 {
30                   //++res;
31                   continue;
32                 }
33                 */ 
34                 if(M[i][j]==1)
35                 {
36                     ++res;
37                     dfs(M,i,j);
38                 }
39             }
40         return res;  
41     }
42     void dfs(vector<vector<int>>& M,int i,int j)
43     {
44         if(!(i>=0&&i<M.size()&&j>=0&&j<M[0].size()))
45         {
46             return;
47         }
48         if(M[i][j]==0)
49         {
50             return;
51         }
52         M[i][j]=0;
53         //if(i==j) return;
54 
55         for(int r = 0;r<M.size();++r)
56         {
57             if(M[r][j]==1&&r!=i)
58             {
59                 dfs(M,r,j);
60             }
61         }
62         for(int c = 0;c<M[0].size();++c)
63         {
64             if(M[i][c]==1&&c!=j)
65             {
66                 dfs(M,i,c);
67             }
68         }
69         return;
70     }
71 };
72 // @lc code=end

 

     本题同样可以并查集的方法解决。代码如下:

/*
 * @Descripttion: 
 * @version: 
 * @Author: wangxf
 * @Date: 2019-12-20 15:21:49
 * @LastEditors: Do not edit
 * @LastEditTime: 2020-04-14 19:49:27
 */
/*
 * @lc app=leetcode.cn id=547 lang=cpp
 *
 * [547] 朋友圈
 */

// @lc code=start
#include<bits/stdc++.h>
using namespace std;

//union find 算法
class UF
{
public:
    // 构造函数初始化
    UF(int n)
    {
        count = n;
        parent.resize(n);
        size.resize(n);
        for(int i = 0; i < n; i++)
        {
            parent[i] =i;
            size[i] = 1;
        }
    }
    // 将节点p 和 节点 q 连通
    void Union(int p, int q)
    {
        int rootP = find(p);
        int rootQ = find(q);
        if(rootP == rootQ)
            return;
        
        if(size[rootP] > size[rootQ])
        {
            parent[rootQ] = rootP;
            size[rootP] += size[rootQ];
        }
        else
        {
            parent[rootP] = rootQ;
            size[rootQ] += rootP;
        }
        count--;//连通个数 -1
    }
    //判断节点p 和 节点 q 是否连通
    bool connected(int p, int q)
    {
        int rootP = find(p);
        int rootQ = find(q);
        return rootP==rootQ;
    }
    //返回当前连通个数
    int count_num()
    {
        return count;
    }
private:
    int count;//连通的个数
    vector<int> parent;//保存节点的父节点
    vector<int> size;//保存节点所在连通分量的重量(节点数)
    
    int find(int x)// 寻找 x 节点的根点
    {
        while(parent[x] != x)
        {
            //查找根节点的同时,对树进行路径压缩,
            parent[x] = parent[parent[x]];
            x = parent[x];
        }
        return x;
    }
};

class Solution {
public:
    int findCircleNum(vector<vector<int>>& M) {
        // base case
        if(M.size()==0)
            return 0;
        
        const int m = M.size();//行数
        const int n = M[0].size();//列数
        //UF* uf = new UF(m);
        UF uf(m);
        for(int i = 0; i < m; i++)
        {
            for(int j = i+1; j < n; j++)//表示朋友圈的矩阵是对称的
            {
                if(M[i][j] == 1)
                {
                    uf.Union(i,j);
                }
            }
        }
        return uf.count_num();
    }
};

// @lc code=end

---------------------------- ------------------------------参考链接---------------------------------------------------------------------------

感谢:

通俗理解并查集:https://blog.csdn.net/niushuai666/article/details/6662911

使用并查集解决朋友圈问题详解: https://github.com/labuladong/fucking-algorithm/blob/master/%E7%AE%97%E6%B3%95%E6%80%9D%E7%BB%B4%E7%B3%BB%E5%88%97/UnionFind%E7%AE%97%E6%B3%95%E8%AF%A6%E8%A7%A3.md

并查集算法应用:https://github.com/labuladong/fucking-algorithm/blob/master/%E7%AE%97%E6%B3%95%E6%80%9D%E7%BB%B4%E7%B3%BB%E5%88%97/UnionFind%E7%AE%97%E6%B3%95%E5%BA%94%E7%94%A8.md

posted @ 2020-04-12 23:35  谁在写西加加  阅读(177)  评论(0编辑  收藏  举报