leetcode-435. 无重叠区间
贪心算法
区间问题
题目详情
给定一个区间的集合 intervals
,其中 intervals[i] = [starti, endi]
。返回 需要移除区间的最小数量,使剩余区间互不重叠 。
示例1:
输入: intervals = [[1,2],[2,3],[3,4],[1,3]]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。
示例2:
输入: intervals = [ [1,2], [1,2], [1,2] ]
输出: 2
解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。
示例3:
输入: intervals = [ [1,2], [2,3] ]
输出: 0
解释: 你不需要移除任何区间,因为它们已经是无重叠的了。
我的代码:
C++
bool mycomp(vector<int>& a, vector<int>& b) //自定义比较规则
{
return a[1]<b[1];
}
class Solution
{
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals)
{
if(intervals.empty()) //检验是否为空
return 0;
int n=intervals.size();
sort(intervals.begin(),intervals.end(),mycomp); //sort函数(含比较规则mycomp)
int removed=0,temp=intervals[0][1];
for(int i=1;i<n;++i)
{
if(intervals[i][0]<temp) //如果区间头小于前一个区间的尾部
++removed; //则移去该区间
else //否则更新temp
temp=intervals[i][1];
}
return removed;
}
};
涉及知识点:
- 贪心算法
顾名思义,贪心算法或贪心思想采用贪心的策略,保证每次操作都是局部最优的,从而使最
后得到的结果是全局最优的。
- C++ sort函数
sort 详解-含比较规则
思路:
一个个区间存储于二维数组中,行代表第几个区间,列的01
代表区间头和尾
利用sort
函数将所有区间排序好,再利用一个循环依次比较移除即可
一个细节: sort函数里的mycomp
函数定义可以利用C++11的Lambda表达式
合并到sort
语句中:Lambda表达式
修改后的最终代码:
C++
class Solution
{
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals)
{
if(intervals.empty())
return 0;
int n=intervals.size();
sort(intervals.begin(),intervals.end(),[](vector<int>& a,vector<int>& b)
{
return a[1]<b[1];
}
);
int removed=0,temp=intervals[0][1];
for(int i=1;i<n;++i)
{
if(intervals[i][0]<temp)
++removed;
else
temp=intervals[i][1];
}
return removed;
}
};
Java
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]; //按照区间尾进行排序
}
});
//removed记录移除区间个数 temp从第一个区间的尾部开始比较
int removed = 0,temp = intervals[0][1];
for (int i = 1; i < intervals.length; ++i){
if (intervals[i][0] < temp) //如果下一个区间的头小于上一个区间的尾(有重叠)
++removed; //则需要移除
else
temp = intervals[i][1]; //否则更新temp继续比较下一个
}
return removed;
}
}
注意:
这道题的排序方法很重要,我们自定义的排序规则需要根据区间尾来排序,而不能根据区间头,因为我们移除重合区间后,要尽量保留尾部较小的区间,以留出更多的空间给后面的区间,这也正是这道题目的贪心所在!
如果是其他题目,排序就要视情况而定
同类型题目:箭射气球