【LeetCode】57. Insert Interval 插入序列

一、概述

输入一个元素为子区间的长序列和一个目标区间,将目标区间插入到长序列中。注意长序列中各元素不重叠,要求插入后不破坏不重叠这一性质。举例如下:

长序列为[[1,2],[3,5],[6,7],[8,10],[12,16]],目标区间为[4,8],要求不重叠,则插入后的长序列为[[1,2],[3,10],[12,16]]。

这道题与第56题相关,最简单的做法是把目标序列push进长序列,然后sort,化为56题做。但是很麻烦,时间复杂度O(nlogn)。我的方法时间复杂度为O(n)。

二、分析

题目很直观,总的来说就是在子区间中找到目标区间左端点left和右端点right的位置,我们维护两个变量now_min和now_max记录位置:

先找左端点的位置:

从头开始遍历整个序列,找到第一个子区间n,它的右端点值大于等于left,则left位置一定在n-1的右端点到n的右端点这部分区间内,即now_min可能取值为n的左端点,此时n的左端点值小于left;或取值为left,此时n的左端点值大于left。

然后找右端点的位置:

右端点可能落在子区间之内,也可以落在子区间之间,因此都需要注意:以n为第一个区间,以n的右端点到n+1的左端点为第二个区间;以此类推。在具体实现时,首先判断第i个区间,然后判断第i个区间和第i+1个区间之间的区间。当right落在区间内时,now_max取值为区间右端点;当right落在区间之间时,now_max取值为right。

当now_min和now_max取值完毕,push到res中,之后使用insert将原序列后面的元素插入res的后面即可。

代码如下:

class Solution {
public:
    vector<vector<int>> insert(vector<vector<int>>& inter, vector<int>& newInter) {
        vector<vector<int>> res;
        if(inter.size()==0)
        {
            res.push_back(newInter);
            return res;
        }
        for(int i=0;i<inter.size();++i)
        {
            if(inter[i][1]<newInter[0])
            {
                res.push_back(inter[i]);
            }
            else
            {
                int now_min=-1;
                if(inter[i][0]<newInter[0])
                    now_min=inter[i][0];
                else
                    now_min=newInter[0];
                int now_max=-1;
                if(inter[i][0]>newInter[1])
                    now_max=newInter[1];
                else
                {
                    for(;i<inter.size();++i)
                    {
                        if(inter[i][0]<=newInter[1]&&inter[i][1]>=newInter[1])
                        {
                            now_max=inter[i][1];
                            break;
                        }
                        if(i==inter.size()-1||(inter[i][1]<=newInter[1]&&inter[i+1][0]>newInter[1]))
                        {
                            now_max=newInter[1];
                            break;
                        }
                    }
                    ++i;
                }
                vector<int> tmp;
                tmp.push_back(now_min);
                tmp.push_back(now_max);
                res.push_back(tmp);
                res.insert(res.end(),inter.begin()+i,inter.end());
                return res;
            }    
        }
        res.push_back(newInter);
        return res;
    }
};

三、总结

双指针法一直是很好用的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值