题目:
给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
注意:
可以认为区间的终点总是大于它的起点。
区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
class Solution {
/*
排序过程:
按照右边界排序,就要从左向右遍历,因为右边界越小越好,只要右边界越小,留给下一个区间的空间就越大,所以从左向右遍历,优先选右边界小的。
按照左边界排序,就要从右向左遍历,因为左边界数值越大越好(越靠右),这样就给前一个区间的空间就越大,所以可以从右向左遍历。
如果按照左边界排序,还从左向右遍历的话,要处理各个区间右边界的各种情况。
*/
// 这题有两个出彩的地方:
// 1、排序是个亮点
// 2、没有直接去求移除区间的个数,而是转换一下思路,先去求非交叉区间的个数
// 用总个数 减去 非交叉区间个数 ,最终求得需要移除的区间个数
// // ***************************方法一:从左向右遍历按照右边界排序
// private:
// static bool cmp(const vector<int>& a, const vector<int>& b)
// {
// // 右边界排序,从左向右遍历
// // 这里对于 a[0] 与 b[0] 的比较 升序、降序 都对,因为后面的处理主要就是看右边界
// // 左边界怎么样都是 可以的!!!!
// // if(a[1] == b[1])
// // {
// // return a[0] < b[0];
// // }
// return a[1] < b[1];
// }
// public:
// int eraseOverlapIntervals(vector<vector<int>>& intervals)
// {
// if(intervals.size() == 0) return 0;
// sort(intervals.begin(), intervals.end(), cmp);
// int result = 1;
// int end = intervals[0][1]; //将按照右边界排序后第一个元素的右下标赋值给end
// for(int i = 1; i < intervals.size(); i++)
// {
// if(end <= intervals[i][0])
// {
// result++;
// end = intervals[i][1];
// }
// }
// // 注意上面获得是无重复区间个数,这里不要忘记用总数做减法哦~~
// return intervals.size() - result;
// }
// ***************************方法二:与引爆气球的思路类似
private:
static bool cmp(const vector<int>& a, const vector<int>& b)
{
// 在本方法中,cmp 函数定义为 对左边界排升序或者是 对右边界排升序 都是对滴!
// return a[1] < b[1];
return a[0] < b[0];
}
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals)
{
if(intervals.size() == 0) return 0;
sort(intervals.begin(), intervals.end(), cmp);
int result = 1; // 记录无重复区间个数
// 第一种 for 循环
for(int i = 1; i < intervals.size(); i++)
{
// 当前第 i 个元素的左边界 月 前一个元素的右边界比较
if(intervals[i][0] < intervals[i - 1][1])
{
// 如果被包含在了前一个元素的右边界,则更新当前元素的右边界,取最小值
intervals[i][1] = min(intervals[i][1], intervals[i - 1][1]);
}
// 如果没有包含,说明是无重复的两个区间,则将无重复区间个数 +1
else
{
result++;
}
}
// // 第二种for循环,两种写法都是对的
// int start = intervals[0][0];
// int end = intervals[0][1];
// for(int i = 1; i < intervals.size(); i++)
// {
// if(intervals[i][0] < end)
// {
// // 更新start 为最大,end 为最小,尽可能缩小范围
// start = max(intervals[i][0], start);
// end = min(intervals[i][1], end);
// }
// else
// {
// result++;
// // 重新个 start 和 end 赋值
// start = intervals[i][0];
// end = intervals[i][1];
// }
// }
return intervals.size() - result;
}
};