Merge Intervals

合并或者插入区间的这类题个人感觉最优的做法是比较像贪心算法,但是因为输入数据的特点太像扫描线了,所以这里自己用了一种扫描线算法强行套到这个题上面去了,所以时间复杂度变为O(nlgn),空间复杂度则为O(n),并且是用了O(4n)的额外空间,不是一个很好的解,但是也表明此题能用扫描线解,下面是代码

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

def comparator(A, B):
    if A[1] == B[1]:
        return A[0] - B[0]
    if A[0] == B[0]:
        return -1 if A[1] else 1
    return A[0] - B[0]

class Solution(object):
    def merge(self, intervals):
        """
        :type intervals: List[Interval]
        :rtype: List[Interval]
        """
        tmp = []
        start = []                # 这里还需要start和end两个额外单独记录起点和终点的数组
        end = []
        for interval in intervals:
            tmp.append([interval.start, 1])
            tmp.append([interval.end, 0])
            start.append(interval.start)
            end.append(interval.end)

        tmp.sort(cmp = comparator)
        start.sort()
        end.sort()
        intervals.sort(cmp = lambda x,y:x.start - y.start)

        res = []
        count = 0
        base, step = 0, 0
        for intv in tmp:
            if intv[1]:
                count += 1
                step += 1
            else:
                count -= 1
                if count == 0:
                    res.append(Interval(start[base], end[base + step - 1]))        # 这一行是很关键的
                    base += step
                    step = 0

        return res

这道题还可以对每一个区间进行类似贪心的检查,即当栈顶的区间和当前遍历的区间有重合时,我们把两个区间合并再放入栈顶,如果没有重合则把当前区间放入栈顶,这样就能得到merge过后的结果了

class Solution(object):
    def merge(self, intervals):
        """
        :type intervals: List[Interval]
        :rtype: List[Interval]
        """
        res = []
        for interval in sorted(intervals, cmp=lambda x, y : cmp(x.start, y.start)):
            if res and res[-1].end >= interval.start:
                res[-1] = Interval(res[-1].start, max(res[-1].end, interval.end))        # 你不知道当前区间是不是比栈顶区间还要大
            else:
                res.append(interval)
        return res

Insert Interval

这题如果直接套merge的第二种解法是可行的,因为本身数组有序,实际上排序的时间复杂度就被减小了,但是应该还有遍历一遍就能搞定的做法,以后再研究

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

        intervals.append(newInterval)
        res = []
        for interval in sorted(intervals, cmp = lambda x, y: cmp(x.start, y.start)):
            if res and res[-1].end >= interval.start:
                res[-1] = Interval(res[-1].start, max(res[-1].end, interval.end))
            else:
                res.append(interval)
        return res

O(n)的做法,毛子哥带你用Python系列...列表可以不用调append函数直接加数进去,只要加个逗号就行了

算法上以newInterval的start和end为中间点,合并一切可以并在一起的interval到这两个变量里面去,其余的或左或右最终相加就可以了

class Solution(object):
    def insert(self, intervals, newInterval):
        """
        :type intervals: List[Interval]
        :type newInterval: Interval
        :rtype: List[Interval]
        """
        start, end = newInterval.start, newInterval.end
        left, right = [], []
        for interval in intervals:
            if interval.end < start:
                left += interval,
            elif interval.start > end:
                right += interval,
            else:
                start = min(start, interval.start)
                end = max(end, interval.end)
        return left + [Interval(start, end)] + right

results matching ""

    No results matching ""