[NeetCode 150] Insert New Interval

Insert New Interval

You are given an array of non-overlapping intervals intervals where intervals[i] = [start_i, end_i] represents the start and the end time of the ith interval. intervals is initially sorted in ascending order by start_i.

You are given another interval newInterval = [start, end].

Insert newInterval into intervals such that intervals is still sorted in ascending order by start_i and also intervals still does not have any overlapping intervals. You may merge the overlapping intervals if needed.

Return intervals after adding newInterval.

Note: Intervals are non-overlapping if they have no common point. For example, [1,2] and [3,4] are non-overlapping, but [1,2] and [2,3] are overlapping.

Example 1:

Input: intervals = [[1,3],[4,6]], newInterval = [2,5]

Output: [[1,6]]

Example 2:

Input: intervals = [[1,2],[3,5],[9,10]], newInterval = [6,7]

Output: [[1,2],[3,5],[6,7],[9,10]]

Constraints:

0 <= intervals.length <= 1000
newInterval.length == intervals[i].length == 2
0 <= start <= end <= 1000

Solution

With binary search, we can find the last interval that its right endpoint is less than left endpoint of new interval, noting the index as pos_le, then find the first interval that its left endpoint is greater than right endpoint of new interval, noting the index as pos_ri.

The new interval must be placed between pos_le and pos_ri interval. If pos_le==pos_ri, it means the new interval is included by an existing interval, we just need to return original intervals. Otherwise, insert one new interval with endpoints [min(newInterval[0], intervals[pos_le+1][0]), max(newInterval[1], intervals[pos_ri-1][1])].

Code

class Solution:
    def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
        intervals = [[-1, -1]] + intervals[:] + [[1001, 1001]]

        le = 0
        ri = len(intervals)-1
        pos_le = -1
        while le <= ri:
            mid = (le+ri)//2
            if intervals[mid][1] < newInterval[0]:
                pos_le = mid
                le = mid+1
            else:
                ri = mid-1

        le = 0
        ri = len(intervals)-1
        pos_ri = -1
        while le <= ri:
            mid = (le+ri)//2
            if intervals[mid][0] <= newInterval[1]:
                le = mid+1
            else:
                pos_ri = mid
                ri = mid-1
        
        print(pos_le, pos_ri)

        if pos_le == pos_ri:
            return intervals[1:-1]
        
        return intervals[1:pos_le+1] + [[min(newInterval[0], intervals[pos_le+1][0]), max(newInterval[1], intervals[pos_ri-1][1])]] + intervals[pos_ri:-1]

Also, we can solve it without binary search

class Solution:
    def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
        res = []

        for i in range(len(intervals)):
            if newInterval[1] < intervals[i][0]:
                res.append(newInterval)
                return res + intervals[i:]
            elif newInterval[0] > intervals[i][1]:
                res.append(intervals[i])
            else:
                newInterval = [
                    min(newInterval[0], intervals[i][0]),
                    max(newInterval[1], intervals[i][1]),
                ]
        res.append(newInterval)
        return res

好的,下面是对这个 `insert` 函数的逐行解释: ```cpp class Solution { public: vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) { // 定义函数接收两个参数:区间列表intervals 和新的区间newInterval,并返回更新后的区间列表 int left = newInterval[0]; // 获取新区间的左边界 int right = newInterval[1]; // 获取新区域右边界 vector<vector<int>> ans; // 创建用于存储最终结果的向量ans int idx = 0; // 初始化索引变量idx,用于遍历输入区间列表intervals // 第一部分处理:将所有在新区间左侧且无交集的区间直接加入到结果集中 while (idx < intervals.size() && intervals[idx][1] < left) { ans.push_back(intervals[idx++]); // 将当前无交集的区间添加进结果中并递增idx } // 第二部分处理:合并与新区间有交集的所有区间 while (idx < intervals.size() && intervals[idx][0] <= right) { newInterval[0] = std::min(newInterval[0], intervals[idx][0]); // 更新合并后的新区间的左边界为较小值 newInterval[1] = std::max(newInterval[1], intervals[idx][1]); // 更新合并后的新区间的右边界为较大值 idx++; // 移动指针继续检查下一个区间是否需要合并 } ans.push_back(newInterval); // 合并将新插入或修改过的区间存入结果数组 // 第三部分处理:将剩余的右侧不相交的区间加回到结果集合里 while (idx < intervals.size()) { ans.push_back(intervals[idx++]); // 把剩下的其他未受影响的部分追加回结果集中去 } return ans; // 返回经过调整后的完整的结果区间列表 } }; ``` ### 总结: 该算法通过三个步骤实现了对给定的一组非重叠有序区间和一个新的待插入区间进行正确的整合操作。 #### 主要思路拆解: 1. **第一步**:先找到不需要改动的位置(即完全位于新区间的左边),把这些元素直接放入输出; 2. **第二步**:遇到第一个与新区间发生冲突的地方开始处理直到不再有冲突为止,在此过程中不断更新新区间的范围直至覆盖完所有相关的旧区间; 3. **第三步**:最后把剩下那些不受影响的部分接续至最终的答案序列之后即可完成整个任务。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值