「这是我参与2022首次更文挑战的第5天,活动详情查看: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 <= 104intervals[i].length == 20 <= starti <= endi <= 104
解题思路
本题需要我们将发生重叠的区间进行合并,并返回一个不重叠的区间数组。
这里我们可以首先对输入数组的子数组按照开始值进行升序排序,这样就保证了前面区间的开始值一定小于等于后面区间的开始值。
此时我们只需要判断如果前面区间的结束值大于等于后面区间的开始值,则说明两个区间发生了重叠,合并两个区间即可。
遍历排序后的输入数组,按照以上逻辑进行判断合并,数组遍历完成,就得到了合并后的结果数组。
动画演示
代码实现
var merge = function (intervals) {
// 特判如果输入数组长度为1,直接返回
if (intervals.length === 1) return intervals
// 对输入数组按照子数组区间开始值升序排序
intervals.sort((a, b) => a[0] - b[0])
// 获取输入数组长度
const len = intervals.length,
// 初始化结果数组
res = []
// 记录待合并区间的开始值的最小值和结束值的最大值
let [min,max] = intervals[0],
// 初始化查找指针
tail = 1;
while (tail < len) {
// 如果当前子区间的开始值小于等于之前区间结束值的最大值,则可以合并
while (tail < len && intervals[tail][0] <= max) {
// 尝试更新区间结束值的最大值
max = Math.max(max, intervals[tail][1])
// tail 指针后移一位
tail++
}
// 当找不到可以继续合并的区间
// 根据当前待合并区间的开始值的最小值和结束值的最大值组成合并区间并插入结果数组
res.push([min, max])
// 更新待合并区间的开始值的最小值和结束值的最大值
if (tail < len) {
[min,max] = intervals[tail]
}
}
// 返回结果数组
return res
}
这里在编码过程中,我们利用了一个小技巧,我们利用一个指针向后查找可以合并的区间,直到无法再找到可合并区间为止,此时再进行区间的合并,这样就减少了多次区间合并的开销。
至此我们就完成了 leetcode-56-合并区间
如有任何问题或建议,欢迎留言讨论!👏🏻👏🏻👏🏻