Merge/Insert interval 区间合并

Merge interval

Given a collection of intervals, merge all overlapping intervals.

For example,
Given [1,3],[2,6],[8,10],[15,18],
return [1,6],[8,10],[15,18].

https://oj.leetcode.com/problems/insert-interval/

Insert interval

Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).

You may assume that the intervals were initially sorted according to their start times.

Example 1:
Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9].

Example 2:
Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16].

This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10].

https://oj.leetcode.com/problems/merge-intervals/


Merge interval

题目:求区间的并集问题,(1,2) (2,3) (5,6) (5,8) 合并后结果为 (1,3) (5,8)。

分析:

  1. 排序,以区间左边的数字关键字排序
  2. 用两个变量left,right分别记录能够合并的区间最左边和最右边的值。如果下一个区间starti<=right,表明两者可以合并,而合并后的right=max(endi, right)。 如果不满足条件,说明无法与该区间合并,则用new Interval(left,right)添加到结果集合中,同时left=starti,right=endi。
  3. 最后i>=len,退出的时候,要把最后一次push_back(Interval(left,right))。
代码:

bool mycompare(Interval a,Interval b){
    return a.start<b.start;
}

class Solution {
public:
    vector<Interval> merge(vector<Interval> &intervals) {
        int len=intervals.size();
        if(len<=1) return intervals;
        vector<Interval> res;
        //排序
        sort(intervals.begin(),intervals.end(),mycompare);
        
        int left=intervals[0].start,right=intervals[0].end;
        for(int i=1;i<len;i++){
            if(intervals[i].start <= right){
                right=max(right,intervals[i].end); //!!取两者较大的值作为right
                //continue;
            }else{
                
                res.push_back(Interval(left,right));
                left=intervals[i].start;
                right=intervals[i].end;
            }
        }
        //添加最后一个
        res.push_back(Interval(left,right));
        return res;
    }
};
 

Insert interval

题目:在一个组有序且无交叉的区间中,插入区间,返回合并后的区间。

分析:

  1. 找到区间该插入的位置,首次 i.end>=new.start的位置。将i之前的所有区间push到结果集合中。
  2. 同merge的方法,取new.start=min(new.start,i.start),取两者较小的值作为start值,然后向后查找,直到 new.end<x.start, 然后取较大的end作为new.end, 将new加入到结果集合中。
  3. 对于剩余的区间,添加到结果集合。
代码:

<pre name="code" class="cpp">class Solution {
public:
    vector<Interval> insert(vector<Interval> &intervals, Interval newInterval) {
        int len=intervals.size();
        vector<Interval> res;
        if(len<1){
            res.push_back(newInterval);
            return res;
        } 
        
        int i=0;
        //添加前半部分不需要合并的
        while(i<len && (intervals[i].end < newInterval.start)){
            res.push_back(intervals[i]);
            i++;
        }
        //合并部分的左值
        if(i<len){
            newInterval.start=min(intervals[i].start,newInterval.start);
        }
        //合并部分的右值
        while(i<len && intervals[i].start <= newInterval.end){
            newInterval.end=max(intervals[i].end,newInterval.end);
            i++;
        }
       res.push_back(newInterval);//合并部分的结果
        while(i<len){ //插入剩余部分
            res.push_back(intervals[i]);
            i++;
        }
        
        return res;
    }
};
 insert interval 问题,在找合并位置时,可以使用二分查找(因为start值是排好序的),可以不申请额外的空间,直接修改输入的区间数组。编程之美上有类似的题目。 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值