Leetcode 2406 将区间分为最少组数
https://leetcode.cn/problems/divide-intervals-into-minimum-number-of-groups/description/
给你一个二维整数数组 intervals ,其中 intervals[i] = [lefti, righti] 表示 闭 区间 [lefti, righti] 。
你需要将 intervals 划分为一个或者多个区间 组 ,每个区间 只 属于一个组,且同一个组中任意两个区间 不相交 。
请你返回 最少 需要划分成多少个组。
如果两个区间覆盖的范围有重叠(即至少有一个公共数字),那么我们称这两个区间是 相交 的。比方说区间 [1, 5] 和 [5, 8] 相交。
示例 1:
输入:intervals = [[5,10],[6,8],[1,5],[2,3],[1,10]]
输出:3
解释:我们可以将区间划分为如下的区间组:
- 第 1 组:[1, 5] ,[6, 8] 。
- 第 2 组:[2, 3] ,[5, 10] 。
- 第 3 组:[1, 10] 。
可以证明无法将区间划分为少于 3 个组。
示例 2:
输入:intervals = [[1,3],[5,6],[8,10],[11,13]]
输出:1
解释:所有区间互不相交,所以我们可以把它们全部放在一个组内。
提示:
1 <= intervals.length <= 10^5
intervals[i].length == 2
1 <= lefti <= righti <= 10^6
贪心解法
将 线段按照起始点从小到排序, 然后操作从一个以结束点从小到大的最小堆中选择查看是否可以放在一组(两线段不重合)。
1 首先我们确认,无论中途还是最终,如果能放在一组 比分开两组更优化。
2 线段按照起始点从小到排序,我们遍历数组保证当前匹配的线段A起点是最小的(线段按照起始点从小到排序),而他匹配的是从堆选择的 终点最小的已经分组的线段B,
如果AB有重合不能匹配分组 ,堆中的其他线段终点只会越来越大,堆中不会有能匹配当前线段A分一组的可能,当前线段A独自为一组放进对
如果AB无重合能分为一组,从堆中弹出线段B,放入线段A,等效为更新B的这一组的终点为A的终点。
3 遍历完整个数组,堆中有几个元素就是分为几组
class Solution {
public:
struct cmpop{
//堆中按照终点从小到大排序
bool operator()(vector<int>&a,vector<int>&b){
if(a[1] > b[1] ) return true;
if(a[1] == b[1]){
if(a[0] < b[0] ) return true;
return false;
}
return false;
}
};
//数组排序 按照起点从小到大排序
static bool cmp(vector<int>& a ,vector<int>& b){
if(a[0] < b[0]) return true;
if(a[1] == b[1]){
if(a[1] < b[1] ) return true;
return false;
}
return false;
}
int minGroups(vector<vector<int>>& intervals) {
sort(intervals.begin(),intervals.end(),cmp);
priority_queue<vector<int>, vector<vector<int>>, cmpop> minHeap;
for(int i= 0;i < intervals.size();i++){
if(minHeap.empty()){
minHeap.push(intervals[i]);
}else{
vector<int> t = minHeap.top();
if(intervals[i][0] > t[1] ){
minHeap.pop(); minHeap.push(intervals[i]);
}else{
minHeap.push(intervals[i]);
}
}
}
return minHeap.size();
}
};
差分解法
将线段起点终点涉及到的范围 视为一个数组,一个线段的起点和终点内所有的计数都加1,那么最后查看数组的记录,数值最大的就是某一个点经过的最大线段数,就是至少需要分配的组数
范围内集体加减 使用差分达到O(n)复杂度
class Solution {
public:
int minGroups(vector<vector<int>>& intervals) {
vector<int> arr(1000010,0);
for(int i=0;i < intervals.size();i++){
int l = intervals[i][0];
int r = intervals[i][1];
arr[l] +=1;
arr[r+1] -=1;
}
int n= 1;
for(int i = 1;i<= 1000000;i++){
arr[i] += arr[i-1];
n=max(n,arr[i]);
}
return n;
}
};
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
浙公网安备 33010602011771号