[LeetCode in Python] 56 (M) merge intervals 合并区间

题目

https://leetcode-cn.com/problems/merge-intervals/

给出一个区间的集合,请合并所有重叠的区间。

示例 1:

输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。

解题思路(欠优雅版)

  • 先按left排序列表
  • 对[0]和[1]这两个范围进行比较
  • 如果相交就合并,更新[0],扔掉[1]
  • 不相交就将[0]添加到结果列表
  • 如此反复对[0]和[1]进行处理,直到列表长度不到2
  • 如果列表仍然有内容,就将其添加到结果列表

代码(欠优雅版)

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        # - sort intervals by left
        intervals = sorted(intervals, key=lambda x:x[0])

        res = []
        while len(intervals)>=2:
            # - if overlap, update [0] and drop [1]
            if intervals[1][0] <= intervals[0][1]:
                intervals[0][1] = max(intervals[0][1], intervals[1][1])
                intervals.pop(1)
            else:
                # - put [0] into res and pop [0]
                res.append(intervals[0])
                intervals.pop(0)

        # - add last one to res if has one
        if intervals:
            res.append(intervals[0])

        return res

解题思路(优雅版)

上一个思路,涉及太多对已有列表的删除操作,其实都是没有必要的。
只需要对结果列表进行处理即可。

  • 先按左边排序
  • 再按序将范围与结果列表的最后一个范围进行合并检查
  • 如果可以合并,就更新结果列表的最后一个范围
  • 否则就将其添加到结果列表末尾

代码(优雅版)

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        # - sort intervals by left
        intervals = sorted(intervals, key=lambda x:x[0])

        res = []
        for x in intervals:
            if not res:
                res.append(x)
            elif x[0] <= res[-1][1]:
                res[-1][1] = max(res[-1][1], x[1])
            else:
                res.append(x)
                
        return res

优化

在排序过的列表中,寻找满足条件的边界,还可以使用二分法进一步优化。

posted @ 2020-04-16 01:00  ET民工[源自火星]  阅读(233)  评论(0编辑  收藏  举报