zoukankan      html  css  js  c++  java
  • LeetCode 547. 朋友圈

    习题地址  https://leetcode-cn.com/problems/friend-circles/

    班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。

    给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果M[i][j] = 1,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。

    示例 1:

    输入: 
    [[1,1,0],
     [1,1,0],
     [0,0,1]]
    输出: 2 
    说明:已知学生0和学生1互为朋友,他们在一个朋友圈。
    第2个学生自己在一个朋友圈。所以返回2。

    示例 2:

    输入: 
    [[1,1,0],
     [1,1,1],
     [0,1,1]]
    输出: 1
    说明:已知学生0和学生1互为朋友,学生1和学生2互为朋友,所以学生0和学生2也是朋友,所以他们三个在一个朋友圈,返回1。

    注意:

    1. N 在[1,200]的范围内。
    2. 对于所有学生,有M[i][i] = 1。
    3. 如果有M[i][j] = 1,则有M[j][i] = 1。

    解答

    并查集常规用法

    并查集简介

     

    数组中的每个数字都指向自己 然后根据从属关系 将数组指向进行改变。

    同一组的元素的顶端元素是一样。与图中稍有区别的是

    元素1 和2的 顶端都是0

     int union[1000];
    
        void init(int n)
        {
            for (int i = 0; i < 1000; i++)
                union[i] = i;
        }    
    //代码实现
    //得到元素所在集合的最顶端
        int get(int x)
        {
            return x == euqal[x] ? x : euqal[x] = get(euqal[x]);
        }
    //将两个集合合并在一起
        void merge(int x, int y)
        {
            euqal[get(x)] = get(y);
        }

    但是不适当的合并 容易造成单链的集合 查找链表最低端的元素属于哪个集合(得到集合顶端元素) 可能会是一个漫长的过程

    比如下图的5元素 要遍历整个集合的全部元素才能达到顶端。

    所以合并的时候 会尽量将合并的上级元素的指向 指向顶点元素

     1 class UnionFind {
     2 public:
     3     vector<int> father;
     4     UnionFind(int num) {
     5         for (int i = 0; i < num; i++) {
     6             father.push_back(i);    //每个人都指向自己
     7         }
     8     }
     9     int Find(int n) {
    10         //非递归版本 
    11         /*
    12         while (father[n] != n) {
    13             n = father[n];
    14         }
    15         return n;
    16         */
    17         //递归
    18         if (father[n] == n)
    19             return n;
    20         father[n] = Find(father[n]);
    21         return father[n] ;
    22     }
    23     void Union(int a, int b) {
    24         int fa = Find(a);
    25         int fb = Find(b);
    26         father[fb] = fa;
    27     }
    28 };
    29 
    30 class Solution {
    31 public:
    32     int findCircleNum(vector<vector<int>>& M) {
    33         int N = M.size();
    34         UnionFind UF(N);
    35         for(int i =0;i < N;i++){
    36             for(int j =0;j<N;j++){
    37                 if(M[i][j]){
    38                     UF.Union(i,j);
    39                 }
    40             }
    41         }
    42         int res = 0;
    43         for(int i=0;i < N;i++){
    44             if(UF.Find(i) == i)
    45                 res++;
    46         }
    47         return res;
    48     }
    49 };
    View Code
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    PyMySQL TypeError: not enough arguments for format string
    使用python3抓取pinpoint应用信息入库
    JS 异步之 async await
    JS Null 空 判断
    Vue问题汇总
    pymysql DAO简单封装
    py可视化执行过程
    jenkins回滚之groovy动态获取版本号
    容器时间 容器乱码问题
    SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Hana]
  • 原文地址:https://www.cnblogs.com/itdef/p/10919862.html
Copyright © 2011-2022 走看看