• 微软面试题:LeetCode. 547. 省份数量 middle 出现次数:1 并查集


    本文参考 Leetcode  547. 省份数量  题解区:https://leetcode-cn.com/problems/number-of-provinces/solution/python-duo-tu-xiang-jie-bing-cha-ji-by-m-vjdr/

    一 . 并查集 

     基本概念

       1. 并查集是一种数据结构;

         2. 并查集这三个字,一个字代表一个意思 ;

         3. 并(Union),代表合并 ;

         4. 查(Find),代表查找 ;

         5. 集(Set),代表这是一个以字典为基础的数据结构,它的基本功能是合并集合中的元素,查找集合中的元素;

         6. 并查集的典型应用是有关连通分量的问题;

         7.  并查集解决单个问题(添加,合并,查找)的时间复杂度都是O(1)O(1);

         8.  因此,并查集可以应用到在线算法中;

      并查集跟树有些类似,只不过它跟树是相反的。在树这个数据结构里面,每个节点会记录它的子节点。在并查集里,每个节点会记录它的父节点。

    合并操作: 对两个节点 u 、 v  ,先使用 Find 操作看是否在一个连通分量,若不在一个连通分量,假设 u 所在连通分量的节点数比 将 v 所

    在连通分量的节点数多。将 v 的根结点 root_v 的父节点设为 u 的根结点 root_u。

    查找操作:查找的过程中执行 路径压缩。

    代码实现   

     1 //union find 算法
     2 class UF
     3 {
     4 public:
     5     // 构造一个并查集
     6     UF(int n)
     7     {
     8         count = n;
     9         parent.resize(n);
    10         weight.resize(n);
    11         for(int i = 0; i < n; i++)
    12         {
    13             parent[i] =i;
    14             weight[i] = 1;
    15         }
    16     }
    17     //并操作, 将节点p 和 节点 q 连通
    18     void Union(int p, int q)
    19     {
    20         //查操作
    21         int rootP = Find(p);
    22         int rootQ = Find(q);
    23         if(rootP == rootQ)
    24             return;
    25        //并操作 
    26         if(weight[rootP] > weight[rootQ])
    27         {
    28             parent[rootQ] = rootP;
    29             weight[rootP] += weight[rootQ];
    30         }
    31         else
    32         {
    33             parent[rootP] = rootQ;
    34             weight[rootQ] += rootP;
    35         }
    36         count--;//连通个数 -1
    37     }
    38     //查操作,查找 x 节点的根点
    39      int Find(int x)
    40     {
    41         while(parent[x] != x)
    42         {
    43            //查找 x 根节点的同时,对树进行路径压缩
    44            parent[x] = parent[parent[x]];
    45             x = parent[x];
    46         }
    47         return x;
    48     }
    49     //判断节点p 和 节点 q 是否连通
    50     bool isConnected(int p, int q)
    51     {
    52         int rootP = Find(p);
    53         int rootQ = Find(q);
    54         return rootP == rootQ;
    55     }
    56     //返回当前连通个数
    57     int getCount()
    58     {
    59         return count;
    60     }
    61 private:
    62     int count;//连通分量的个数
    63     vector<int> parent;//保存节点的父节点
    64     vector<int> weight;//保存节点所在连通分量的重量(节点数)
    65 };

    二 . 省份数量

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 //union find 算法
     5 class UF
     6 {
     7 public:
     8     // 构造一个并查集
     9     UF(int n)
    10     {
    11         count = n;
    12         parent.resize(n);
    13         weight.resize(n);
    14         for(int i = 0; i < n; i++)
    15         {
    16             parent[i] =i;
    17             weight[i] = 1;
    18         }
    19     }
    20     //并操作, 将节点p 和 节点 q 连通
    21     void Union(int p, int q)
    22     {
    23         //查操作
    24         int rootP = Find(p);
    25         int rootQ = Find(q);
    26         if(rootP == rootQ)
    27             return;
    28        //并操作 
    29         if(weight[rootP] > weight[rootQ])
    30         {
    31             parent[rootQ] = rootP;
    32             weight[rootP] += weight[rootQ];
    33         }
    34         else
    35         {
    36             parent[rootP] = rootQ;
    37             weight[rootQ] += rootP;
    38         }
    39         count--;//连通个数 -1
    40     }
    41     //查操作,查找 x 节点的根点
    42      int Find(int x)
    43     {
    44         while(parent[x] != x)
    45         {
    46            //查找 x 根节点的同时,对树进行路径压缩
    47            parent[x] = parent[parent[x]];
    48             x = parent[x];
    49         }
    50         return x;
    51     }
    52     //判断节点p 和 节点 q 是否连通
    53     bool isConnected(int p, int q)
    54     {
    55         int rootP = Find(p);
    56         int rootQ = Find(q);
    57         return rootP == rootQ;
    58     }
    59     //返回当前连通个数
    60     int getCount()
    61     {
    62         return count;
    63     }
    64 private:
    65     int count;//连通分量的个数
    66     vector<int> parent;//保存节点的父节点
    67     vector<int> weight;//保存节点所在连通分量的重量(节点数)
    68 };
    69 
    70 class Solution {
    71 public:
    72     int findCircleNum(vector<vector<int>>& M)
    73     {
    74         // specila case
    75         if(M.size() == 0)
    76             return 0;
    77         const int n = M.size();
    78         UF uf(n);//创建一个并查集对象
    79         for(int i = 0; i < n; i++)
    80         {
    81             for(int j = i+1; j < n; j++)//表示朋友圈的矩阵是对称的
    82             {
    83                 if(M[i][j] == 1)
    84                 {
    85                     uf.Union(i,j);
    86                 }
    87             }
    88         }
    89         return uf.getCount();
    90     }
    91 };
  • 相关阅读:
    windows 环境下 eclipse + maven + tomcat 的 hello world 创建和部署
    使用IntelliJ IDEA 14和Maven创建java web项目
    使用Spring JDBCTemplate简化JDBC的操作
    CSS颜色代码 颜色值 颜色名字大全
    mysql创建数据库命令
    win64位安装python-mysqldb1.2.3
    UVA11426 欧拉函数
    关于gcd的几个问题
    POI2007_zap 莫比乌斯反演
    BZOJ2005 莫比乌斯反演
  • 原文地址:https://www.cnblogs.com/wangxf2019/p/14724071.html
Copyright © 2020-2023  润新知