【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升序;所以一定要会重写比较器接口;

相关题目

455. 分发饼干

452. 用最少数量的箭引爆气球

376. 摆动序列

860. 柠檬水找零

122. 买卖股票的最佳时机 II

134. 加油站

406. 根据身高重建队列

56. 合并区间

738. 单调递增的数字


__EOF__

本文作者Curryxin
本文链接https://www.cnblogs.com/Curryxin/p/15132913.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Curryxin  阅读(168)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
Live2D
欢迎阅读『【LeetCode】【贪心】435. 无重叠区间』
点击右上角即可分享
微信分享提示