LeetCode刷题(python版)——Topic57插入区间

一、题设

给你一个 无重叠的 ,按照区间起始端点排序的区间列表。

在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。

示例 1:

输入:intervals = [[1,3],[6,9]], newInterval = [2,5]
输出:[[1,5],[6,9]]

示例 2:

输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
输出:[[1,2],[3,10],[12,16]]
解释:这是因为新的区间 [4,8][3,5],[6,7],[8,10] 重叠。

示例 3:

输入:intervals = [], newInterval = [5,7]
输出:[[5,7]]

示例 4:

输入:intervals = [[1,5]], newInterval = [2,3]
输出:[[1,5]]

示例 5:

输入:intervals = [[1,5]], newInterval = [2,7]
输出:[[1,7]]

二、基本思路

        首先看到这题有点像上题的做法,但又不是很相同,问题是在于插入一个在合并,合并只需要考虑相邻范围有无重叠,而插入既要考虑相邻是否合并还要考虑一下插入的范围与左右范围的前后顺序,是左右分离(相对左、相对右两种情况),还是有交集。于是我起初是这么写的:

for l,r in intervals:
    if left > r:# 插入区间在右边
        res.append([l,r])
    elif right < l: # 插入区间在左边
        res.append([left,right])
    else: # 修改left、right值
        left = min(l,left)
        right = max(r,right)

        这段代码的意思就是:

        1.left > r : 当intervals = [[1,2]](l=1,r=2),newInterval = [[3,4]](left=3,right=4),则先加入[l,r],写到这里就发现问题了:intervals已经遍历完了,但是[3,4]并没有插入其中。

        2.right < l : 当intervals = [[3,4]](l=3,r=4),newInterval = [[1,2]](left=1,right=2),则先加入[left,right],同样这里的[3,4]也没有加入res中。

        3. else:代表有重合的部分,那么目前的范围就是左端最小与右端最大,即[min(l,left),max(r,right)]。

        我们假装不知道哪里有问题提交一下,看看有啥样例过不了:

        没毛病,果然不出所料,也是之前发现的问题,如何解决?

        虽然之前的例子中都是[3,4]没有插入,但是一个是intervals一个是newInterval。那么我们再看一下上面没过的样例:在遍历intervals中,到最后一个[6,9]是执行l > right,所以我们可以在最后加一个res.append([l,r])把这个[6,9]加上去。

        for l,r in intervals:
            if left > r:# 插入区间在右边
                res.append([l,r])
            elif right < l: # 插入区间在左边
                res.append([left,right])
                res.append([l,r])
            else: # 修改left、right值
                left = min(l,left)
                right = max(r,right)

        结果发现还是不过: 

         问题出在如果intervals数组只有一个元素且与newInterval有交集时,就会产生left,right有值但还没有来得及往res中存的问题。于是我们加上:res.append([left,right]):

        for l,r in intervals:
            if left > r:# 插入区间在右边
                res.append([l,r])
            elif right < l: # 插入区间在左边
                res.append([left,right])
                res.append([l,r])
            else: # 修改left、right值
                left = min(l,left)
                right = max(r,right)
                res.append([left,right])

        又又又报错了,是啥子原因呢?是因为两个res.append([left,right])重复了,于是我们使用一个tag标志位保证两个只能成立一个

        tag = True
        for l,r in intervals:
            if left > r:# 插入区间在右边
                res.append([l,r])
            elif right < l: # 插入区间在左边
                if tag:
                    res.append([left,right])
                    tag = False
                res.append([l,r])
            else: # 修改left、right值
                left = min(l,left)
                right = max(r,right)
                if tag:
                    res.append([left,right])
                    tag = False

         结果:

         错误原因是当[3,5]换完上下边界值的时候,因为tag已经是False了,所以[6,7]和[8,10]比较了但是没有存入res中,最后我们想到把tag放到最外面

        心态波了,理不清这种题的关系,完全是在碰答案... 

三、代码实现

def insert(self, intervals, newInterval):
        if not intervals:
            return [newInterval]
        left,right = newInterval # left,right记录每个结果的左右值
        res = []
        tag = True
        for l,r in intervals:
            if left > r:# 插入区间在右边
                res.append([l,r])
            elif right < l: # 插入区间在左边
                if tag:
                    res.append([left,right])
                    tag = False
                res.append([l,r])
            else: # 修改left、right值
                left = min(l,left)
                right = max(r,right)
        if tag:
            res.append([left,right])
        return res

四、效率总结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值