1353.最多可以参加的会议数目

题目在这里插入图片描述
分析:
贪心:
对于一个时间点, 所有之前已经开始的会议和但是此刻还没有结束的会议均可以参加;
但是每个时间点只可以参加一个会议,选择结束时间最小的参加

1.先记录每一天正在进行的会议
  for(int i = 0; i < events.size(); i++) {
  	for(int j = events[i][0]; j <= events[i][1]; j++) {
  		meetings[j].emplace_back(i); 
  	}
  }
2.对于每一天来说,这一天所应该参加的会议是meetings[j]中的会议索引值中的一个,应该选择最先结束的那一个.最先结束的会议可以用小顶堆来确定.
3.但是该代码超出了时间限制.
class Solution {
public:
    struct cmp {
        bool operator() (pair<int, int>& x, pair<int, int>& y) {
            return x.first > y.first;
        } 
    };
    int maxEvents(vector<vector<int>>& events) {
        int MAX = 1e5 + 1;
        int count = 0;
        if(events.empty()) return 0;
        vector<vector<int>> left(MAX);
        for(int i = 0; i < events.size(); i++) {
            for(int j = events[i][0]; j <= events[i][1]; j++) {
                left[j].emplace_back(i);
            }
        }

        vector<bool> visited(events.size(), false);
        priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> pq;
        for(int i = 1; i < MAX; i++) {
            while (!pq.empty()) pq.pop();
            for(auto j: left[i]) {
                if(!visited[j]) {
                    pq.push(pair<int, int>(events[j][1], j));
                }
            }
            if(!pq.empty()) {
                pair<int, int> temp = pq.top();
                visited[temp.second] = true;
                count++;
            }
        }
        return count;
    }
};
思路二
1. 记录每一天有哪些会议开始了
2. 对于第i天,这个人要参加的会议必须满足:
   (1)已经开始了=>通过left数组控制
   (2)还没结束 pq.top() < i, 说明pq内endDay最小的会议已经结束了,这个值应该被弹出了
   (3)过滤完所有的这些开不了的,选取endDay最小的,把它开了,并且弹出
class Solution {
public:
    int maxEvents(vector<vector<int>>& events) {
        int MAX = 1e5 + 1;
        int count = 0;
        if(events.empty()) return 0;
        vector<vector<int>> left(MAX);
        for(int i = 0; i < events.size(); i++) {
            left[events[i][0]].emplace_back(i);
        }

        vector<bool> visited(events.size(), false);
        priority_queue<int, vector<int>, greater<int>> pq;
        for(int i = 1; i < MAX; i++) {
            for(auto j: left[i]) {
                pq.push(events[j][1]);
            }
            while(!pq.empty() && pq.top() < i) {
                pq.pop();
            }
            if(!pq.empty()) {
                pq.pop();
                count++;
            }
        }
        return count;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值