57.插入区间- 力扣(LeetCode)

题目:

        给你一个 无重叠的 ,按照区间起始端点排序的区间列表 intervals,其中 intervals[i] = [starti, endi] 表示第 i 个区间的开始和结束,并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval = [start, end] 表示另一个区间的开始和结束。

        在 intervals 中插入区间 newInterval,使得 intervals 依然按照 starti 升序排列,且区间之间不重叠(如果有必要的话,可以合并区间)。

        返回插入之后的 intervals。

注意 你不需要原地修改 intervals。你可以创建一个新数组然后返回它。

示例 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] 重叠。

提示:

  • 0 <= intervals.length <= 104

  • intervals[i].length == 2

  • 0 <= starti <= endi <= 105

  • intervals 根据 starti 按 升序 排列

  • newInterval.length == 2

  • 0 <= start <= end <= 105

思路如下:

        此题与56题无限近似。我们把新的区间加入,然后按照左边界排序。因为题目交代起始端点是有序排列的,我们可以使用二分插入到数组中。最后则是56题的解法遍历数组合并区间。

题解如下:
class Solution:
    def insert(self, intervals, newInterval):
        """
                        :type: intervals: List[List[int]], newInterval: List[int]
                        :rtype:  List[List[int]]
        """
        # 使用bisect.insort插入新区间,保持按起始端点排序
        bisect.insort(intervals, newInterval)
        
        #56题解法,合并区间
        ans = []
        for interval in intervals:
            # 如果结果列表不为空且当前区间可以合并
            if ans and interval[0] <= ans[-1][1]:
                # 合并区间,更新结束点为较大者
                ans[-1][1] = max(ans[-1][1], interval[1])
            else:
                # 否则直接加入结果列表
                ans.append(interval)
        return ans

时间复杂度为O(n),空间复杂度为O(n),其中 n 是区间的数量。

注意事项:

1.为什么 bisect.insort 默认基于起始端点排序?

Python 的默认比较规则:当比较两个列表(如 [a, b] 和 [c, d])时,Python 会先比较第一个元素 a 和 c,若相等再比较第二个元素 b 和 d。因此,bisect.insort 在插入 newInterval 时,会按起始端点(第一个元素)排序。

2.如何改为基于终止端点排序?

bisect.insort(intervals, newInterval, key=lambda x: x[1])

3.python自带的bisect库(标准库)

例子:a = [3, 5, 6, 10] b=6

  • bisect.bisect(a,b) #第一个bisect是库名,第二个bisect是模块名

  • bisect和insort的默认情况均是排在右边

  • bisect.bisect_left(a,b)排在左边

  • bisect.bisect(a,b)是获得插入位置,bisect.insort是直接二分插入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值