并查集 LeetCode 547. 朋友圈

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

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

链接:https://leetcode-cn.com/problems/friend-circles
 

由于这道题的n*n方阵中的n只有200,所以dfs、bfs、并查集都可以做,并且我也没有进行路径压缩。
class Solution {
public:
    int findCircleNum(vector<vector<int>>& M) {
        int n = M.size();
        int p[n];
        for (int i = 0; i < n; ++i) p[i] = i;
        for (int i = 0 ; i < n; ++i)
            for (int j = 0 ; j < n; ++j){
                if (i == j) continue;  // 对角线不用看,因为自己肯定在自己的朋友圈中。
                else if (M[i][j]){
                    M[j][i] = 0;
                    int x = i;
                    while(p[x] != x) x = p[x];  // 找祖先
                    int y = j;
                    while(p[y] != y) y = p[y];  // 找祖先
                    p[y] = x;   // 统一让[i][j]中的下标为j的同学归于下标为i的同学
                }
            }
        int cnt = 0;
        for (int i = 0; i < n; ++i)  // 最后只要查数组p[]中有几个点是头结点就可以了,也就是看有几个朋友圈
            if (p[i] == i) cnt++; 
        return cnt;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值