LeetCode之HOT100--056 合并区间

154 阅读2分钟

「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」。

前言

一直都计划学习数据结构与基本算法,但是平时都看一阵停一阵。现在决心坚持下去,我准备从LeetCode的HOT100开始,每天完成1~2道习题,本系列的题解都将使用swift语言完成。本文更新的是LeetCode中HOT100的第26题056 合并区间。

题目

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。 示例 1:

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

示例 2:

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

提示

1 <= intervals.length <= 104
intervals[i].length == 2
0 <= starti <= endi <= 104

分析

本题的目的是将多个数值区间进行合并整理,所以我们在合并之前需要将数据区间进行排序,按照区间的start进行排序(也可以按照区间的end进行排序),然后根据当前区间和前一个已经合并好的区间进行比较整理。基本思路如下:\

  1. 将所有数值区间按照start从小到大的顺序进行排序,得到排序后的区间数组 sortIntervals
  2. 创建临时数组result保存最后的结果集
  3. 遍历sortIntervals,依次处理每个区间 inteval,具体处理规则如下:
  • 3.1 如果结果集为空,则直接将 inteval 添加到 结果集result中
  • 3.2 如果结果集不为空,则取出结果集中最后一个区间topInteval,如果topInteval与inteval有重叠,则合并topInteval与inteval的区间,并将新的区间替换topInteval,如果没有重叠,则将 inteval 添加到结果集中

需要注意的是由于 sortIntervals 中的区间是按照start从小到大的顺序进行排好序的,所以 result 中的区间也是按照start从小到大排序的,并且result中的区间的start一定比sortIntervals中的当前区间inteval的start小,所以判断topInteval与inteval是否重叠时,只需要判断所以判断topInteval的end值 是否小于 inteval的start值 即可,小于则表示没有重叠。

题解

class Solution {
    func merge(_ intervals: [[Int]]) -> [[Int]] {
        //按照区间的start从小到大进行排序
        let sortIntervals = intervals.sorted { (arr1:[Int], arr2:[Int]) -> Bool in
            return (arr1.first! <= arr2.first!)
        }
        //临时变量result保存最后的结果集
        var result:[[Int]] = []
        //遍历,逐个处理排序后的区间
        for inteval in sortIntervals {
            if result.isEmpty {
                //如果结果集为空,则直接将当前区间添加到结果集中
                result.append(inteval)
            } else {
                //如果结果集不为空,则取出结果集中最后一个区间,与当前区间进行判断,有重叠则合并,没有重叠则将当前区间添加到结果集中
                var topInteval = result.last!
                if topInteval[1] < inteval[0] {
                    //没有重叠
                    result.append(inteval)
                } else {
                    //有重叠,则合并两个区间
                    topInteval[1] = max(topInteval[1], inteval[1])
                    result.removeLast()
                    result.append(topInteval)
                }
            }
        }
        return result
    }
}