• 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]]

    二、基本思路

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

    1. for l,r in intervals:
    2. if left > r:# 插入区间在右边
    3. res.append([l,r])
    4. elif right < l: # 插入区间在左边
    5. res.append([left,right])
    6. else: # 修改left、right值
    7. left = min(l,left)
    8. 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]加上去。

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

            结果发现还是不过: 

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

    1. for l,r in intervals:
    2. if left > r:# 插入区间在右边
    3. res.append([l,r])
    4. elif right < l: # 插入区间在左边
    5. res.append([left,right])
    6. res.append([l,r])
    7. else: # 修改left、right值
    8. left = min(l,left)
    9. right = max(r,right)
    10. res.append([left,right])

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

    1. tag = True
    2. for l,r in intervals:
    3. if left > r:# 插入区间在右边
    4. res.append([l,r])
    5. elif right < l: # 插入区间在左边
    6. if tag:
    7. res.append([left,right])
    8. tag = False
    9. res.append([l,r])
    10. else: # 修改left、right值
    11. left = min(l,left)
    12. right = max(r,right)
    13. if tag:
    14. res.append([left,right])
    15. tag = False

             结果:

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

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

    三、代码实现

    1. def insert(self, intervals, newInterval):
    2. if not intervals:
    3. return [newInterval]
    4. left,right = newInterval # left,right记录每个结果的左右值
    5. res = []
    6. tag = True
    7. for l,r in intervals:
    8. if left > r:# 插入区间在右边
    9. res.append([l,r])
    10. elif right < l: # 插入区间在左边
    11. if tag:
    12. res.append([left,right])
    13. tag = False
    14. res.append([l,r])
    15. else: # 修改left、right值
    16. left = min(l,left)
    17. right = max(r,right)
    18. if tag:
    19. res.append([left,right])
    20. return res

    四、效率总结

  • 相关阅读:
    Unity——利用Mesh绘制图形
    【Java-LangChain:面向开发者的提示工程-4】文本概括
    基于javaweb+mysql的新闻发布管理系统
    在vite初始化的项目中安装scss,及scss的使用
    机器学习运用-民宿价格
    Redis5种数据类型
    编辑任何场景! 3DitScene:通过语言引导的解耦 Gaussian Splatting开源来袭!
    设计模式:里氏代换原则(Liskov Substitution Principle,LSP)介绍
    C/C++编程 —— 读取和保存 TXT 文本
    YOLOv6又快又准的目标检测框架 已开源
  • 原文地址:https://blog.csdn.net/weixin_54039182/article/details/127734760