57.Insert Interval

Tags: [queue], [interval], [merge], [insert]

Com: {fb}

Link: https://leetcode.com/problems/insert-interval/\#/description

Given a set ofnon-overlappingintervals, 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:
Given intervals[1,3],[6,9], insert and merge[2,5]in as[1,5],[6,9].

Example 2:
Given[1,2],[3,5],[6,7],[8,10],[12,16], insert and merge[4,9]in as[1,2],[3,10],[12,16].

This is because the new interval[4,9]overlaps with[3,5],[6,7],[8,10].


Solution: Queue

# Definition for an interval.
# class Interval(object):
#     def __init__(self, s=0, e=0):
#         self.start = s
#         self.end = e

from collections import deque

class Solution(object):
    def insert(self, intervals, newInterval):
        """
        :type intervals: List[Interval]
        :type newInterval: Interval
        :rtype: List[Interval]
        """
        if not newInterval:
            return intervals
        if not intervals:
            return [newInterval]

        queue = deque()
        for i in xrange(len(intervals)):
            interval = intervals[i]

            if self.can_merge(interval, newInterval):
                self.merge_intervals(interval, newInterval)
                newInterval = None
                queue.append(interval)
                continue

            elif self.can_insert(intervals, i, newInterval):
                queue.append(newInterval)
                queue.append(interval)
                newInterval = None
                continue

            if not queue or not self.can_merge(queue[-1], interval):
                queue.append(interval)
            else:
                self.merge_intervals(queue[-1], interval)

        if newInterval:
            queue.append(newInterval)

        return list(queue)

    def can_merge(self, interval1, interval2):
        if not interval1 or not interval2:
            return False

        left = interval1 if interval1.start <= interval2.start else interval2
        right = interval1 if interval1.start > interval2.start else interval2

        return left.end >= right.start

    def merge_intervals(self, interval1, interval2):
        interval1.start = min(interval1.start, interval2.start)
        interval1.end = max(interval1.end, interval2.end)

    def can_insert(self, intervals, index, new_interval):
        if not new_interval:
            return False

        if index == 0:
            return new_interval.end < intervals[index].start

        return intervals[index - 1].end < new_interval.start and\
               new_interval.end < intervals[index].start

Revelation:

  • First whether current interval can merge with newInterval, if they cannot be merged, then check can we insert the newInterval at the position i. Be careful the following cases: (1) intervals = [[1, 5]], newInterval = [0, 3]; (2) intervals = [[1, 3], [10, 15]], newInterval = [5, 6]. (3) Intervals = [[1, 3]], newInterval = [10, 15].

Note:

  • Time complexity = O(n), n is the number of intervals.
  • Space complexity = O(n), n is the number of intervals.
  • Need check the following, at the beginning of the 'can_insert' function:
if not new_interval:
    return False

results matching ""

    No results matching ""