小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题目描述
以数组 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].
思路1
- 先将所有区间按照起始位置排序,那么只需要比较相邻两个区间的结束位置就能知道它们是否重叠
- 如果它们重叠就将它们合并,然后判断合并的区间是否和下一个区间重叠
实现
var merge = function (intervals) {
if (intervals == null || !intervals.length) {
return intervals;
}
intervals.sort((a, b) => {
return a[0] - b[0];
});
let result = [];
let i = 0;
while (i < intervals.length) {
// 当前区间
let cur = [intervals[i][0], intervals[i][1]];
let j = i + 1;
// 如果下一个区间的开始位置还要小于等于当前区间的结束位置,则有重叠,
while (j < intervals.length && intervals[j][0] <= cur[1]) {
// 合并后的结束位置应该取两个区间结束位置的最大值
cur[1] = Math.max(cur[1], intervals[j][1]);
j++;
}
result.push(cur);
i = j;
}
return result;
};
思路2 => 妙用reduce
- 先排序,后合并,再reduce中acc代码上一次计算的结果。
- 如果上一次能合并的话,acc就是合并后的结果。
- 不能的话acc为上一个数组。
- 最后一项就是reduce的最后结果,因为没有比较,所以直接用res接住返回值
var merge = function(intervals) {
if(intervals.length == 0){
return intervals;
}
intervals.sort((a, b) => a[0] - b[0]);
let res = [];
res.push(intervals.reduce((acc, cur) => {
if(acc[1] >= cur[0]){
if(acc[1] < cur[1]){
acc[1] = cur[1];
}
return acc;
}else{
res.push(acc);
return cur;
}
}));
return res;
};
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤