2406. 将区间分为最少组数

231 阅读2分钟

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,既我们贪心该堆顶元素,并将其更新。后续小根堆会自动排序。
  • 如果堆顶元素right\geqleft,既我们堆内其余元素均不满足要求(其余元素均比堆顶元素大),故我们将该区间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插入。【510】
* 当第三个元素到来,将left元素和堆顶元素5比较,不符合要求,right插入。【3510】
* 当第四个元素到来,将left元素5和堆顶元素3比较,符合要求,right更新堆顶。【10510->【51010】
* 当第五个元素到来,将left元素和堆顶元素5比较,符合要求,right插入。【81010->【81010】
* 返回堆的大小元素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();
    }
};