小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【LeetCode 56. 合并区间 】- JavaScript
题目描述
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
思路1:
prev 初始为第一个区间,cur 表示当前的区间,res 表示结果数组
- 开启遍历,尝试合并 prev 和 cur,合并后更新到 prev
- 合并后的新区间还可能和后面的区间重合,继续尝试合并新的 cur,更新给 prev
- 直到不能合并 —— prev[1] < cur[0],此时将 prev 区间推入 res 数组
核心策略 => 合并
- 原则上要更新prev[0]和prev[1],即左右端:
- prev[0] = min(prev[0], cur[0])
- prev[1] = max(prev[1], cur[1])
- 但如果先按区间的左端排升序,就能保证 prev[0] < cur[0]
- 所以合并只需这条:prev[1] = max(prev[1], cur[1])
注意:我们是先合并,遇到不重合再推入 prev。 当考察完最后一个区间,后面没区间了,遇不到不重合区间,最后的 prev 没推入 res。 要单独补上。
var merge = function (intervals) {
let res = [];
intervals.sort((a, b) => a[0] - b[0]);
let prev = intervals[0];
for (let i = 1; i < intervals.length; i++) {
let cur = intervals[i];
if (prev[1] >= cur[0]) { // 有重合
prev[1] = Math.max(cur[1], prev[1]);
} else { // 不重合,prev推入res数组
res.push(prev);
prev = cur; // 更新 prev
}
}
res.push(prev);
return res;
};
思路2:贪心 => splice+sort
思路:
- 先sort排序,以intervals中starti升序排序,再进行遍历。
- 如果下一元素的starti在当前元素内部则用splice方法删除这两个区间,并加入新区间。
- 新区间starti为intervals[i][0],endi为intervals[i+1][1]和intervals[i][1]中较大的那个值,并且i--。
- 最后当intervals[i+1]为undefined则跳出循环,返回合并好的intervals
var merge = function (intervals) {
intervals.sort((a, b) => a[0] - b[0])
for (let i = 0; i < intervals.length; i++) {
if (intervals[i + 1] == undefined) {
break
}
if ((intervals[i][0] <= intervals[i + 1][0]) && (intervals[i][1] >= intervals[i + 1][0])) {
intervals.splice(i, 2, [intervals[i][0], intervals[i][1] > intervals[i + 1][1] ? intervals[i][1] : intervals[i + 1][1]]);
i--
}
}
return intervals
};
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤