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。
注意:
- N 在[1,200]的范围内。
- 对于所有学生,有M[i][i] = 1。
- 如果有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元素 要遍历整个集合的全部元素才能达到顶端。
所以合并的时候 会尽量将合并的上级元素的指向 指向顶点元素
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 };
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
![阿里打赏](https://files.cnblogs.com/files/itdef/ali2.bmp)
![微信打赏](https://files.cnblogs.com/files/itdef/weixin2.bmp)