微软面试题: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 };

 

posted @ 2021-05-01 12:41  谁在写西加加  阅读(99)  评论(0编辑  收藏  举报