给出一个无重叠的 ,按照区间起始端点排序的区间列表。
在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。
链接:https://leetcode-cn.com/problems/insert-interval/
/*基本思想:先找到要插入的区间的位置,拆入之后,区间合并
如果插入式头,那就从后面判断合并的区间,找后面的start大于插入区间end的位置(第一个不重叠的),重叠合并,不重叠之间加入结果
如果是插入中间部分,从插入的位置从前找不重叠的部分加入结果,end<i的start为重叠,先确定合并区间的头,尾先不能确定,将插入的区间的尾编程当前重叠区间最大的,防止后面还可能合并,
然后找后面第一个不重叠的部分,重叠的合并,不重叠的直接加入结果
*/
class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
int i=0,j=0;
vector<vector<int>> res;
vector<int> new_inter;
if(intervals.size()==0)
{
res.push_back(newInterval);
return res;
}
while( i<intervals.size()&&intervals[i][0]<=newInterval[0] ) //找到要插入的位置为i
{
i++;
}
intervals.insert(intervals.begin()+i,newInterval); //插入区间
if(i!=0){ //如果插入不是头部插入
while( j<i&&intervals[i][0]>intervals[j][1] ) //找到第一个不重叠的区域
{
res.push_back(intervals[j]);
j++;
}
new_inter.push_back(intervals[j][0]); //重叠区域合并的start
intervals[i][1] = max(intervals[i][1],intervals[j][1]);
cout<<intervals[i][1]<<endl;
j=i+1;
if(j>=intervals.size())
{
new_inter.push_back(intervals[i][1]);
res.push_back(new_inter);
return res;
}
while( j<intervals.size()&&intervals[i][1]>=intervals[j][0] ) //后面找第一个不重叠的
{
j++;
}
new_inter.push_back(max(intervals[j-1][1],intervals[i][1])); //重叠区域合并找到合并的end
res.push_back(new_inter);
while(j<intervals.size()) //不重叠的直接加入结果
{
res.push_back(intervals[j]);
j++;
}
}
else
{
j=i+1;
while(j<intervals.size() && intervals[i][1]>=intervals[j][0] ) //找后面的start大于插入区间end的位置(第一个不重叠的)
j++;
new_inter.push_back(intervals[i][0]); //插入的区间判断合并
new_inter.push_back(max(intervals[j-1][1],intervals[i][1])); //重叠部分的end取最大的
res.push_back(new_inter);
while(j<intervals.size()) //之后全部不重叠直接加入就好
{
res.push_back(intervals[j]);
j++;
}
}
return res;
}
};
给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
注意:
可以认为区间的终点总是大于它的起点。
区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
链接:https://leetcode-cn.com/problems/non-overlapping-intervals
class Solution {
public:
/*贪心:按数组首数字从小到大排序,然后判断区间:判断尾元素有下面几种情况
1.i的尾<=j的头 无重叠,可以让i变为j,然后j继续向后移动比较
2.i的尾>j的头,有重叠, 则删除i和j尾大的同时数量count加1
如果i的尾大:则i=j 用j代替i j++ 向后比较
如果j的尾大:则i不变,j++,向后比较
*/
static bool cmp(const vector<int> a,const vector<int> b)
{
return a[0]<b[0];
}
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
sort(intervals.begin(),intervals.end(),cmp);
int i=0,j=1;
int count=0;
for(j=1;j<intervals.size();j++)
{
if(intervals[i][1] <= intervals[j][0])
{
i=j;
}
else
{
if(intervals[i][1] > intervals[j][1])
i=j;
count++;
}
}
return count;
}
};
给出一个区间的集合,请合并所有重叠的区间。
链接:https://leetcode-cn.com/problems/merge-intervals/
/*基本思想:两种方法 都先把数组按照开始值从小到大排序
方法一:从开始遍历,找第一个end<start的位置,就是不重叠的位置,前面重叠的部分合并,确定合并的end,确定新的区间,然后继续找下一个与新区间的end不重叠的位置
方法二:直接遍历比较,首先插入一个区间,继续插入的时候判断是否重叠,重叠,更新刚插入的区间的end,否则插入新的区间,利用vector的back函数可以取到最后拆入的区间,直接比较更新就好
*/
class Solution {
public:
static bool cmp(vector<int> a, vector<int> b)
{
return a[0]<b[0];
}
/* vector<vector<int>> merge(vector<vector<int>>& intervals) {
int i=0,j=0;
vector<vector<int>> res;
if(intervals.size()==0)
return res;
sort(intervals.begin(),intervals.end(),cmp);
while(i<intervals.size())
{
int end;
vector<int>cur;
cur.push_back(intervals[i][0]);
end = intervals[i][1];
j=i+1;
while(j<intervals.size() && end>=intervals[j][0] )
{
end = max(end,intervals[j][1]);
j++;
}
cur.push_back(end);
i=j;
res.push_back(cur);
}
return res;
}*/
vector<vector<int>> merge(vector<vector<int>>& intervals) {
vector<vector<int>> res;
if(intervals.size()<1){
return res;
}
sort(intervals.begin(),intervals.end(),cmp);
res.push_back(intervals[0]);
for(int i=1;i<intervals.size();i++){
if(intervals[i][0]<=res.back()[1]){
res.back()[1]=max(intervals[i][1],res.back()[1]);
}
else{
res.push_back(intervals[i]);
}
}
return res;
}
};
给定两个由一些闭区间组成的列表,每个区间列表都是成对不相交的,并且已经排序。
返回这两个区间列表的交集。
(形式上,闭区间 [a, b](其中 a <= b)表示实数 x 的集合,而 a <= x <= b。两个闭区间的交集是一组实数,要么为空集,要么为闭区间。例如,[1, 3] 和 [2, 4] 的交集为 [2, 3]。)
链接:https://leetcode-cn.com/problems/interval-list-intersections
/*基本思路:思路1:以B为基准,A和B依次比较,当A的最大值大于B的最小值的时候,才有交集,求出交集排除异常情况即可
思路2: A和B同时移动比较,不满足交集条件的一方移动(每个集合都是有序的),满足条件则判断交集
*/
class Solution {
public:
/* vector<vector<int>> intervalIntersection(vector<vector<int>>& A, vector<vector<int>>& B) {
int i,j=0;
vector<vector<int>> result;
if(A.size()==0)
return A;
if(B.size()==0)
return B;
for(i=0;i<A.size();i++)
{
vector<int> r;
for(j=0;j<B.size();j++){
if(A[i][1]<B[j][0])
continue;
int left =max(A[i][0],B[j][0]);
int right =min(A[i][1],B[j][1]);
if(left<=right)
{
r.push_back(left);
r.push_back(right);
result.push_back(r);
r.clear();
}
}
}
return result;
}*/
vector<vector<int>> intervalIntersection(vector<vector<int>>& A, vector<vector<int>>& B) {
int cnt = 0;
vector<vector<int>> vec;
vector<int> tmp(2);
for(int i=0;i<A.size()&&cnt<B.size();)
{
if(A[i][0]>B[cnt][1])
{
cnt++;
}
else if(A[i][1]<B[cnt][0])
{
i++;
}
else if(A[i][1]<B[cnt][1])
{
tmp[0] = max(A[i][0],B[cnt][0]);
tmp[1] = A[i][1];
vec.push_back(tmp);
i++;
}
else
{
tmp[0] = max(A[i][0],B[cnt][0]);
tmp[1] = B[cnt][1];
vec.push_back(tmp);
cnt++;
}
}
return vec;
}
};