给出一个区间的集合,请合并所有重叠的区间。
输入: [[1,3],[2,6],[8,10],[15,18]], 1
输出: [[1,6],[8,10],[15,18]]。 2
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6]
方法一 合并重叠
思路:
从示例入手:[1, 3] [2, 6] 是否可以合并只要对比 [1, 3]的最大值 3,[2, 6]的最小值 2,3 >= 2 ,则说明可以合并,否则不能。.[1, 3] [2, 6] [8,10],从3个来看,如果 [2, 6]的最大值6 <= [8,10]的最小值 8,则说明[2, 6] 不能和 [8,10],因此 [1, 3] [2, 6] 执行合并操作,[8,10] 继续与下一个数组执行步骤一。
详解
- 对区间进行排序(升序)
- 从第一区间起取当前拟合并区间为a,
- 取下一区间为b(如果没有b了则输出a,退出)
- 如果a的尾 > b 的头 ,则合并为 a,否则输出a,把b作为a
代码
function getMerge(arr) {
arr.sort((a, b) => {
if(a[0] !== b[0]){
return a[0] - b[0]
}
return a[1] - b[1]
})
let len = arr.length, ans = [],start, end; // 遍历当前区间的最小值与最大值
for(let i = 0; i < len; i++){
let s = arr[i][0];
let e = arr[i][1];
if(start === undefined){
start = s;
end = e;
}
else if(s <= end){
end = Math.max(e, end)
}
else{
let part = [start, end];
ans.push(part);
start = s;
end = e;
}
}
if (start !== undefined) {
let part = [start, end];
ans.push(part);
}
return ans;
}
方案2 合并重叠
详解
- 对区间进行排序(升序)
- 定义一个新的数组,用于存储新的数组区间。
- 从第二个值开始遍历原数组,比较当前区间的最小值是否大于新数组最后一个区间的最大值,如果满足则push进入新的数组;又或者比较当前区间的最大值是否大于新新数组的随后一个区间的最大值,若满足则将新数组的最后一个区间的最大值替换成当前区间的最大值。
代码
function getMerge(arr) {
if (!arr || arr.length === 0) {
return [];
}
let input = arr.sort((a, b) => a[0] - b[0]);
let res = [];
res.push(input[0]);
for(let i = 1, len = input.length; i < len; i++) {
if (input[i][0] > res[res.length - 1][1]) {
res.push(input[i]);
} else if (input[i][1] > res[res.length - 1][1]){
res[res.length - 1][1] = input[i][1];
}
}
return res;
}