看完本文,可以顺便解决leetcode以下题目:
435.无重叠区间(中等)
一、通俗易懂的 贪心算法 |思想 (重复一次~~~)
贪心算法就是采用贪心的策略,保证每一次的操作都是局部最优的,从而使得结果是全局最优的。
比如,A、B、C、都很喜欢吃橘子,A可以吃5个、B可以吃3个、C可以吃1个;但是现在只有7个橘子,问最多几个人可以吃饱;
我们选用的贪心策略就是,吃的少的人先吃,尽量先使用量少的人吃饱,所以在这里,B、C肯定是可以吃饱的;
在这里,又因为全局结果是局部结果的简单求和,因此,局部最优的策略同样也是全局最优的策略。
二、区间问题
435.无重叠区间(中等)
题目描述
给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠
来源:力扣(LeetCode)
输入输出样例
输入: [ [1,2], [2,3], [3,4], [1,3] ]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。
来源:力扣(LeetCode)
题解
首先,我们能够看出来,重叠的判断条件是: 一号区间的区头 < 二号区间的区尾。;所以区尾的元素越小,可以留下来的区间数目就越多,自然移除的区间数目就更少了;
所以此题的贪心策略是:不能重叠,优先保留区尾的元素小的区间。
所以,我们第一步,应该对于当前的区间集合,做一个排序,按照各个区间区尾的值进行增序排序;然后进行判断,保留下来不重叠的区间,同时对于去除区间的操作进行计数;
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 total = 0;
int prev = intervals[0][1];
for (int i = 1; i < n; ++i) {
if (intervals[i][0] < prev) {
// 下一个区头比区尾小 说明和下一个重合了
++ total;
} else {
prev = intervals[i][1]; // 继续下一个
}
}
return total;
}
};