# 57. Insert Interval

**<font color=red>难度: Hard</font>**

## 刷题内容

> 原题连接

* https://leetcode.com/problems/insert-interval/description/

> 内容描述

```
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).

You may assume that the intervals were initially sorted according to their start times.

Example 1:

Input: intervals = [[1,3],[6,9]], newInterval = [2,5]
Output: [[1,5],[6,9]]
Example 2:

Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
Output: [[1,2],[3,10],[12,16]]
Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].
```

## 解题方案

> 思路 1
******- 时间复杂度: O(NlgN)******- 空间复杂度: O(N)******



因为原intervals是有序且non-overlapping的，所以打算直接用56题的代码AC，beats 73.53%

```python
class Solution(object):
    def insert(self, intervals, newInterval):
        """
        :type intervals: List[Interval]
        :type newInterval: Interval
        :rtype: List[Interval]
        """
        if not intervals or len(intervals) == 0:
            return [newInterval]
        res = []
        for interval in sorted(intervals+[newInterval], key = lambda x: (x.start, x.end)):
            if res and res[-1].end >= interval.start:
                res[-1].end = max(res[-1].end, interval.end)
            else:
                res.append(interval)
        return res
```




> 思路 2
******- 时间复杂度: O(N)******- 空间复杂度: O(N)******

考虑到之前的题目条件中的intervals本身就是有序这个特征，觉得排序没有必要，只要先插入，再看看是否需要merge即可

这样时间复杂度减到了O(N), beats 97.49%

```python
class Solution(object):
    def insert(self, intervals, newInterval):
        """
        :type intervals: List[Interval]
        :type newInterval: Interval
        :rtype: List[Interval]
        """
        if not intervals or len(intervals) == 0:
            return [newInterval]
        idx = -1
        for i in range(len(intervals)):
            if intervals[i].start > newInterval.start:
                idx = i
                break
        if idx != -1:
            intervals.insert(i, newInterval)
        else:
            intervals.append(newInterval)
        res = []
        for interval in intervals:
            if res and res[-1].end >= interval.start:
                res[-1].end = max(res[-1].end, interval.end)
            else:
                res.append(interval)
        return res
```

> 思路 3
******- 时间复杂度: O(N)******- 空间复杂度: O(N)******

寒神的二分法, beats 97.49%

```python
from bisect import bisect_left, bisect
class Solution(object):
    def insert(self, intervals, newInterval):
        """
        :type intervals: List[Interval]
        :type newInterval: Interval
        :rtype: List[Interval]
        """
        inter = [v for i in intervals for v in (i.start, i.end)]
        start, end = newInterval.start, newInterval.end
        i, j = bisect_left(inter, start), bisect(inter, end)
        if i & 1:
            i -= 1
            start = inter[i]
        if j & 1:
            end = inter[j]
            j += 1
        inter[i:j] = [start, end]
        return [Interval(s, e) for s, e in zip(inter[::2], inter[1::2])]
```





















