2091.找出所有秘密的专家

找出所有秘密的专家

[题目链接] (https://leetcode.cn/problems/find-all-people-with-secret/description/)

题目类型: 并查集

题目难度: ☀️☀️

解题思路:

利用并查集,在同一场会议的专家合并为一个集合,若是这场会议的专家均不知道秘密,就把这个集合分解。用一个secret数组表示专家是否知道秘密,即“打标签”。

以下是AC代码:

class Solution {
public:
    
int father[100010]; bool secret[100010];

int find(int i){ 
    if(i != father[i]){
		father[i] = find(father[i]); // 扁平化
    }
    return father[i];
}

void Union(int x, int y){
    int fx = find(x), fy = find(y);
    if(fx != fy){
        father[fx] = fy;
        secret[fy] = secret[fy] | secret[fx];
        secret[fx] = secret[fx] | secret[fy]; // 不相等则必有一个专家知道秘密
    }
}

vector<int> findAllPeople(int n, vector<vector<int>>& meetings, int firstPerson) {
    int m = meetings.size();
    for(int i = 0; i < n; i++){ // 初始化
        father[i] = i;
        secret[i] = false;
    }
    father[firstPerson] = 0;
    secret[0] = true; secret[firstPerson] = true;
    sort(meetings.begin(), meetings.end(), [](vector<int> &a, vector<int> &b){
        return a[2] < b[2];
    }); // 按照会议开始的时间升序排列
    for(int l = 0, r; l < m; ){
        r = l;
        while(r + 1 < m && meetings[r][2] == meetings[r+1][2]) // 找到开始时间相同的会议区间[l, r]
{
            r++;
        }
        for(int i  = l; i <= r; i++){
			Union(meetings[i][0], meetings[i][1]);
        } // 把同一时间开会的专家合并
        for(int i = l; i <= r; i++){ // 同一时间开会的专家没有一个知道秘密的,分解这个集合
            int a = meetings[i][0];
            int b = meetings[i][1];
            if(!secret[find(a)]) father[a] = a;
            if(!secret[find(b)]) father[b] = b;
        }
        l = r + 1; // 继续寻找下一时间开始的会议
    }
    vector<int> ans; // 遍历一遍专家的secret数组,true即为所求
    for(int i = 0; i < n; i++){
		if(secret[father[i]]) ans.push_back(i);
    }
    return ans;
	}
};
  • 26
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值