思路:
题目的主要信息:
- n个活动,有各自的区间
- 一个主持人不能在相交的区间工作
- 将相交的区间分成一组,最后组数即是主持人的数量
- 数字为int型的范围,可能会出现负数
方法一:排序+遍历比较
具体做法:
利用辅助数组单独各个活动开始的时间和结束时间,然后分别进行排序。遍历个活动,如果某个活动开始的时间大于之前活动结束的时候,当前主持人就够了,活动结束时间往后一位,若是出现之前活动结束时间晚于当前活动开始时间的,需要增加主持人。
class Solution {
public:
int minmumNumberOfHost(int n, vector<vector<int> >& startEnd) {
vector<int> start;
vector<int> end;
for(int i = 0; i < n; i++){
start.push_back(startEnd[i][0]);
end.push_back(startEnd[i][1]);
}
//分别对开始和结束时间排序
sort(start.begin(), start.end());
sort(end.begin(), end.end());
int res = 0;
int j = 0;
for(int i = 0; i < n; i++){
if(start[i] >= end[j]) //新开始的节目大于上一轮结束的时间,主持人不变
j++;
else
res++; //主持人增加
}
return res;
}
};复杂度分析:
- 时间复杂度:
,遍历都是
,sort排序为
- 空间复杂度:
,辅助空间记录开始时间和结束时间的数组
方法二:重载sort+大顶堆
具体做法:
重载sort函数,优先排开始时间小的,相同情况下再考虑结束时间较小的。
使用小顶堆辅助,其中堆顶是还未结束的将要最快结束的活动的结束时间。首先将int的最小数加入堆中,遍历每一个开始时间,若是堆顶的结束时间小于当前开始时间,可以将其弹出,说明少需要一个主持人;除此之外,每次都需要将当前的结束时间需要加入堆中,代表需要一个主持人,最后遍历完成,堆中还有多少元素,就需要多少主持人。
class Solution {
public:
static bool comp(vector<int>& a, vector<int>& b){ //优先比较开始时间,再比较结束时间
if(a[0] == b[0])
return a[1] < b[1];
else
return a[0] < b[0];
}
int minmumNumberOfHost(int n, vector<vector<int> >& startEnd) {
sort(startEnd.begin(), startEnd.end(), comp);
priority_queue<int, vector<int>, greater<int> > q; //小顶堆
q.push(INT_MIN); //可能有负区间
for(int i = 0; i < n; i++){
if(q.top() <= startEnd[i][0]) //最近的活动结束时间小于当前活动开始时间
q.pop();
q.push(startEnd[i][1]);
}
return q.size();
}
};复杂度分析:
- 时间复杂度:
,sort排序是
,一次遍历,循环中维护堆每次
- 空间复杂度:
,堆大小最大为n

京公网安备 11010502036488号