tips
- 构建大顶堆
priority_queue<int,vector<int>,less<int> >max_heap; - 构建小顶堆
priority_queue<int,vector<int>,greater<int> >small_heap;
题目描述
给你一个二维整数数组 intervals ,其中 intervals[i] = [lefti, righti] 表示 闭 区间 [lefti, righti] 。
你需要将 intervals 划分为一个或者多个区间 组 ,每个区间 只 属于一个组,且同一个组中任意两个区间 不相交 。
请你返回 最少 需要划分成多少个组。
如果两个区间覆盖的范围有重叠(即至少有一个公共数字),那么我们称这两个区间是 相交 的。比方说区间 [1, 5] 和 [5, 8] 相交。
解题思路
- 将区间数组
intervals按照left的值进行递增排序排序。 - 用小根堆进行模拟,存了每一组的最
right元素,并在加尾部加区间后自动排序,时间复杂度为O(logn) - 如果堆顶元素
right待插入区间的left,既我们贪心该堆顶元素,并将其更新。后续小根堆会自动排序。 - 如果堆顶元素
rightleft,既我们堆内其余元素均不满足要求(其余元素均比堆顶元素大),故我们将该区间right插入堆内。后续小根堆会自动排序。
输入: intervals = [[5,10],[6,8],[1,5],[2,3],[1,10]]
排序后:intervals = [[1,5],[1,10],[2,3],[5,10],[6,8]]
* 当地一个元素右侧到来,堆空,right插入,【5】
* 当第二个元素到来,将left元素和堆顶元素5比较,不符合要求,right插入。【5,10】
* 当第三个元素到来,将left元素和堆顶元素5比较,不符合要求,right插入。【3,5,10】
* 当第四个元素到来,将left元素5和堆顶元素3比较,符合要求,right更新堆顶。【10,5,10】->【5,10,10】
* 当第五个元素到来,将left元素和堆顶元素5比较,符合要求,right插入。【8,10,10】->【8,10,10】
* 返回堆的大小元素3。
tips: 这道题有点像数据结构中的火车入栈问题,既火车按顺序出站台,应该是有的,可以找找。
class Solution {
public:
int minGroups(vector<vector<int>>& intervals) {
//构造一个空的优先队列,此优先队列是一个小顶堆
priority_queue<int,vector<int>,greater<int> > small_heap;
sort(intervals.begin(),intervals.end());
for(int i=0;i<intervals.size();i++){
if(!small_heap.empty()&&small_heap.top()<intervals[i][0]){
small_heap.pop();small_heap.push(intervals[i][1]);
}
else if(!small_heap.empty()&&small_heap.top()>=intervals[i][0]){
small_heap.push(intervals[i][1]);
}
else small_heap.push(intervals[i][1]);
}
return small_heap.size();
}
};