携手创作,共同成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
合并区间
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
分析
- 方法:先排序,后合并
- 首先把集合按照左区间排序
- 然后实施合并,把合并之前的区间设为old,区间的首尾分别为start和end,当前的区间为current,新的区间为new,有以下几种情况:
- 当old和current没有交集,即old.end < current.start,那么new.start = old.start,new.old=current.old
- 当old和current有交集,当old.end >= current.start,那么new.start = old.start,new.end=max(current.end,old.end)=current.end
- 当old和current有交集,当old.end >= current.end,那么new.start = old.start,new.end=max(current.end,old.end)=old.end
代码
/**
* @param {number[][]} intervals
* @return {number[][]}
*/
function merge(intervals) {
if (!intervals.length) return intervals
intervals.sort((a, b) => a.start !== b.start ? a.start - b.start : a.end - b.end)
var prev = intervals[0]
var res = [prev]
for (var curr of intervals) {
if (curr.start <= prev.end) {
prev.end = Math.max(prev.end, curr.end)
} else {
res.push(curr)
prev = curr
}
}
return res
}
顺便回顾下排序算法
排序算法
- 可分为两类:原地算法和非原地算法
- 原地算法指的是算法在更改输入内容时不需要额外的空间,但是可以在进行这些操作时使用少量的非固定大小的空间比如指针,常见的冒泡排序、选择排序、插入排序、堆排序都会原地重新排列元素,因此都属于原地算法。关于快速排序,虽然也是直接操作待排序数组,但是因为采取了分治的策略,因此额外多了O(logn)个空间来管理待排序数组。但通常也被认为是原地算法。
- JavaScript数组的sort方法属于原地算法,并且默认的排列顺序是把元素转为字符串,通过比较字符串各个字符的Unicode码从而排序,sort方法的参数是一个比较函数,函数入参有两个,表示需要比较的两个元素
- 本题中就是重写了比较算法,首先比较需要比较的两个区间的开始边界,按照左边界由小到大的顺序排列待排序区间,如果左边界一样,按照右边界从小到大排序,当区间排序完成后,按照分析中的三种情况,依次对区间进行合并
总结
- 排序算法是基础算法之一,因为JavaScript有内置的sort函数,就直接使用了,后面考虑会使用JavaScript来实现基础的排序算法
- 今天也是有收获的一天