一维差分(扫描线)之区间重叠
参考资料来源灵神在力扣所发的题单,仅供分享学习笔记和记录,无商业用途。
核心思路:查看一维差分(扫描线)基础篇-CSDN博客
应用场景:差分仅适用于区间修改、最终查询或多次区间修改后单次查询的场景
56. 合并区间
题意:给定一个区间数组,将重叠区间重新构建,未重叠区间不做处理
思路:先按起点进行排序,后遍历保证当前区间的起点一定大于等于前一个区间的起点,判断前一个区间的终点是否大于等于当前区间的起点即可知道是否重叠,在判断哪个终点大重新更新结果即可。最终遍历使得重叠部分全部重构,不重叠区间不做修改
class Solution {
public:vector<vector<int>> merge(vector<vector<int>>& intervals) {//题意:给定一个区间数组,将重叠区间重新构建,未重叠区间不做处理//思路:先按起点进行排序,后遍历保证当前区间的起点一定大于等于前一个区间的起点,判断前一个区间的终点是否大于等于当前区间的起点即可知道是否重叠,在判断哪个终点大重新更新结果即可。最终遍历使得重叠部分全部重构,不重叠区间不做修改sort(intervals.begin(),intervals.end());vector<vector<int>> ans;for(auto&x:intervals){if(!ans.empty() && ans.back()[1]>=x[0]) ans.back()[1]=max(ans.back()[1],x[1]);else ans.push_back(x);}return ans;}
};
57. 插入区间
题意:给定一组升序区间数组和一个区间,要求按照升序插入区间数组并且有重叠部分必须合并区间。整个区间数组是没有重叠区间的
思路:先将区间插入数组,按照起点进行升序排序,思路同56最终将重叠区间进行合并完成
class Solution {
public:vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {//题意:给定一组升序区间数组和一个区间,要求按照升序插入区间数组并且有重叠部分必须合并区间。整个区间数组是没有重叠区间的//思路:先将区间插入数组,按照起点进行升序排序,思路同56最终将重叠区间进行合并完成intervals.push_back(newInterval);sort(intervals.begin(),intervals.end());vector<vector<int>> ans;for(auto&x:intervals){if(!ans.empty() && ans.back()[1]>=x[0]) ans.back()[1]=max(ans.back()[1],x[1]);else ans.push_back(x);}return ans;}
};
732. 我的日程安排表 III
题意:动态给定时间区间,要求统计从开始到现在所有的时间区间最大重叠区间个数
思路:采用差分哈希表进行区间标记,最后通过前缀和获得重叠区间最大个数
class MyCalendarThree {
public:map<int,int> m;MyCalendarThree() {}//题意:动态给定时间区间,要求统计从开始到现在所有的时间区间最大重叠区间个数//思路:采用差分哈希表进行区间标记,最后通过前缀和获得重叠区间最大个数int book(int startTime, int endTime) {int buff=0,ret=0;m[startTime]++;m[endTime]--;for(auto [x,y]:m){buff+=y;ret=max(ret,buff);}return ret;}
};/*** Your MyCalendarThree object will be instantiated and called as such:* MyCalendarThree* obj = new MyCalendarThree();* int param_1 = obj->book(startTime,endTime);*/
2406. 将区间分为最少组数
题意:给定一组区间数组给分割成多组,要求各个组中无重叠区间。求最小划分多少个组
思路:用差分哈希表标记重叠区间,将最大重叠区间数量视为划分多少个组,这样能确保组内无论如何搭配都不会出现重叠,也就是最小划分组数。
class Solution {
public:int minGroups(vector<vector<int>>& intervals) {//题意:给定一组区间数组给分割成多组,要求各个组中无重叠区间。求最小划分多少个组//思路:用差分哈希表标记重叠区间,将最大重叠区间数量视为划分多少个组,这样能确保组内无论如何搭配都不会出现重叠,也就是最小划分组数。map<int,int> m;for(auto&x:intervals){m[x[0]]++;m[x[1]+1]--;}int buff=0,ret=0;for(auto [x,y]:m){buff+=y;ret=max(ret,buff);}return ret;}
};