「这是我参与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进行排序),然后根据当前区间和前一个已经合并好的区间进行比较整理。基本思路如下:\
- 将所有数值区间按照start从小到大的顺序进行排序,得到排序后的区间数组 sortIntervals
- 创建临时数组result保存最后的结果集
- 遍历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
}
}