题目![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/3fac0f2804a4424450ade709e12bc6df.png)
分析:
贪心:
对于一个时间点, 所有之前已经开始的会议和但是此刻还没有结束的会议均可以参加;
但是每个时间点只可以参加一个会议,选择结束时间最小的参加
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;
}
};