「这是我参与2022首次更文挑战的第37天,活动详情查看:2022首次更文挑战」
题目
以数组 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 <= 10的4次方
intervals[i].length == 2
0 <= starti <= endi <= 10的4次方
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/me… 著作权归领扣网络所有。
解题思路
- 将区间转换成括号:左区间转换成做括号
[l, 1]
,右区间转换成右括号[r, -1]
。 - 然后将转换结果进行排序,先按数字排升序,数字相同的按括号排降序。
- 最后遍历排序后的结果,累计括号的和,当和为0时说明左右括号匹配上了,上一个数字和当前数字为一个合并好的区间。
示例1 [[1,3],[2,6],[8,10],[15,18]] 的处理过程如下图,[1,3] 和 [2,6] 合并后为一个区间。
代码实现
var merge = function(intervals) {
const arr = []
//把区间转换成括号,1代表左括号,-1代表右括号
for (const [l, r] of intervals) {
arr.push([l, 1])
arr.push([r, -1])
}
//排序:先按区间数字排升序,如果数组一样则再按括号排倒序
arr.sort((a, b) => a[0] === b[0] ? b[1] - a[1] : a[0] - b[0])
const ans = []
let l = -1 //记录区间左侧数字
let sum = 0 //累计括号的和
for (const [a, b] of arr) {
//如果需要,将a设置为区间左侧的数字
if (l === -1) l = a
//累计括号的值
sum += b
//和为0时说明遇到了右括号,则[l, a]为一个有效的合并后的区间
if (sum === 0) {
ans.push([l, a])
//将左括号重置为-1
l = -1
}
}
return ans
};
如有错误欢迎指出,欢迎一起讨论!