zoukankan      html  css  js  c++  java
  • [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

  • 相关阅读:
    Linux 命令大全
    MySQL 存储 utf8mb4
    PHP房贷计算器代码,等额本息,等额本金
    laravel 原生 sql
    include_once 问题
    laravel count distinct
    微信小程序显示cms里的html文章
    PHP文件上传
    Ajax做无刷新分页
    PHP封装返回Ajax字符串和JSON数组
  • 原文地址:https://www.cnblogs.com/wangxf2019/p/12688668.html
Copyright © 2011-2022 走看看