题干
给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
注意:
- 可以认为区间的终点总是大于它的起点。
- 区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
示例 1:
输入: [ [1,2], [2,3], [3,4], [1,3] ]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。
解法:贪心
这道题也是使用贪心的思想,子问题实际上就是区间两两之间的接触情况,这样逐步局部最优会最终到达全局最优。
第一步:我们要将二维数组按照第二个元素进行排序,为什么要选择第二个而不是第一个呢?因为区间第二个元素都是较大数,可以准确确定区间的范围。
第二步:从下标为1开始循环遍历二维数组,与它上一个区间进行比较,如果等于或者大于或者等于,则向后遍历,并且记录上一个区间的变量移至当前下标处。如果是小于,记录,但是上一个区间下标不动,直至循环结束
代码实现:
执行用时:96 ms, 在所有 JavaScript 提交中击败了38.91%的用户
内存消耗:39.4 MB, 在所有 JavaScript 提交中击败了73.68%的用户
var eraseOverlapIntervals = function (intervals) {
if (intervals.length == 0 || intervals.length == 1) {
return 0
}
intervals.sort(function (a, b) {
return a[1] - b[1]
})
var pre = 0;//记录上一个节点
var removeNum = 0;
for (let i = 1; i < intervals.length; i++) {
if (intervals[i][0] >= intervals[pre][1]) {
pre = i;//因为中途可能有删除的数组区间,直接++会将其算进结果内
} else {
removeNum++;
}
}
return removeNum
};
**优化方案:**如何对上面代码进行优化,就是我们再循环遍历时完全可以再不符合条件是不用设置一个removeNum来进行记录我们要删除区间值,我们可以再else时直接continue出循环,在符合条件时设置一个addAll这就是来记录我们共符合多少次条件,但是需要注意的是,我们循环是从1开始的,因此addAll默认值要设置为1而不是0,如果设置为0那么我们的值会总是多一个。在循环结束后我们得到了addAll的值,我们使用区间总长度length减去addAll的值就是我们筛出的区间数量了
代码实现:
执行用时:76 ms, 在所有 JavaScript 提交中击败了97.93%的用户
内存消耗:39.5 MB, 在所有 JavaScript 提交中击败了40.60%的用户
var eraseOverlapIntervals2 = function (intervals) {
if(intervals.length==0||intervals.length==1){
return 0
}
intervals.sort(function (a, b) {
return a[1] - b[1]
})
var pre = 0;//记录上一个节点
var addAll = 1;
var length=intervals.length
for (let i = 1; i < length; i++) {
if (intervals[i][0] >= intervals[pre][1]) {
addAll++
pre=i;//因为中途可能有删除的数组区间,直接++会将其算进结果内
} else {
continue
}
}
return length-addAll
};
console.log(eraseOverlapIntervals2([[1,2], [1,2], [1,2]]))