【LeetCode】【贪心】435. 无重叠区间
【贪心】435. 无重叠区间
知识点:贪心;
题目描述
给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
注意:
可以认为区间的终点总是大于它的起点。
区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
示例
输入: [ [1,2], [2,3], [3,4], [1,3] ]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。
输入: [ [1,2], [1,2], [1,2] ]
输出: 2
解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。
输入: [ [1,2], [2,3] ]
输出: 0
解释: 你不需要移除任何区间,因为它们已经是无重叠的了。
解法一:贪心
贪心其实是动态规划的一个特例,贪心算法需要满足更多的条件,但是只要满足条件,贪心算法要更快;
贪心是什么呢,简单来说就是每一步我们都选择在此时的最优解,也就是当前的局部最优解,最终的结果就是全局最优了。它所做的只是当前来看最好的选择,而并不管全局。比如说如果想从一堆人民币里拿10张怎么拿能拿的最多,很显然每次都从剩下的钱里拿最大的就可以了,那最后一定是最多的。
贪心问题的关键就是要选择贪心策略,对于一个问题可以有很多贪心策略,但是很多策略都不能够得到正确答案。如何能得到一个正确的贪心策略没有固定的模板,需要的是经验。
我们把这道题目转化一下思路:移除最小数量,然后区间互不重叠,那反过来,其实就是在求这个区间最多有几个互不相交的空间,得到这个结果之后,拿总个数减去就是需要移除的最小个数了。
像这个问题还有很多,可以把其统一称为:区间调度问题。基本上就是给很多个区间,找出这个区间内最多有多少个不重叠的。比如此题,再比如说在一天内有很多活动。每个活动有自己的时间段,问一天最多能参加几个活动呢。这也是求区间内最多有几个不相交的空间。关键就是要去找一种调度策略。
我们怎么来计算一个区间内最多有几个不相交的空间呢,怎么选择贪心策略呢,比如我们可以选择区间开始最早的那个,但是一想又不行,万一这个是开始的早,但是它维持时间长呢;那我们选择区间时间最短的? 其实也不行,想一下比如有个区间很短,但是呢它正好和前后两个长的都有交集,所以一旦选择这个短的,那我们长的就不能选了,很显然也错误。
正确的贪心策略:
我们从所有区间里选择结束时间最早的,也就是右区间最小的,然后把与其相交的就不要了,接着选择这个区间走完之后下一个的。(就是想让一个区间早点结束开始下一个)
这道题目贪心贪的就是谁先结束;
流程:
1.按结束时间排序;
2.如果此区间与上一区间不重叠,那可以安排;
3.直到遍历完所有区间;
其实是一种最自然朴素的贪心法,我们看哪件事情能最早结束,就先去做它,也就是把结束早的都依次做了,那最后就是做的最多的。数学上也是可以证明的,但是在做题时不必纠结这个问题。重要的是一种经验的积累。
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if(intervals.length == 0) return 0;
Arrays.sort(intervals, new Comparator<int[]>(){
public int compare(int[] a, int[] b){
return a[1]-b[1]; //按end的升序排序;
}
});
int end = intervals[0][1]; //初始化结尾;
int count = 1;
for(int[] inter : intervals){
int start = inter[0]; //区间的开始;
if(start >= end){
count++; //找到了互补重叠的区间;
end = inter[1]; //更新end;
}
}
return intervals.length-count;
}
}
体会
- 要学会重写Comparator接口,可以按照自己的意愿就行排序;
Collections.sort(list, new Comparator<Node>() {
/**o1-o2为升序序排列,o2-o1为降序排列,若具体到某一字段,则根据该字段进行排列*/
@Override
public int compare(Node o1, Node o2) {
if (o1.x==o2.x) //若x属性相等,根据y来升序
return o1.y-o2.y;
return o1.x-o2.x;//x属性不相等,根据x来升序排列
}
});
- 涉及到数对的,一般都会对数对中的某一个维度进行排序,或者两个维度都排序,比如说区间调度按照结尾排序,比如说重建队列按照身高降序,按照k升序;所以一定要会重写比较器接口;