贪心算法:区间问题(一)
主要涉及 :
(一)LeetCode 题435、605
一、区间相交(中等)
1. 题解
贪心算法求解:区间尾部小,留给其余区间的裕度较大,则删除的最少。所以需要对区间尾部进行排序,每次选择结尾小且与前一区间不相交的区间,即后一个区间的头必须不小于前一个区间尾巴。
2. 匿名函数lambda表达式
匿名函数(英文名:lambda)就是没有名字的函数。最简单的匿名函数是[](){}
,它没有参数也没有返回值。
[]
里面用来捕获函数外部的变量
()
里面是匿名函数的参数
{}
里面是函数的执行代码
3. 解题代码
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
int intervalsNum = intervals.size();
int counter = 1; //不需要移除的区间数量
//对每个区间的end做排序,尽可能选结尾小的区间。
if(intervalsNum == 0)
{
return 0;
}
//lambda设计sort函数comp参数实现自定义排序方式:
sort(intervals.begin(),intervals.end(),[](const auto& a,const auto& b){
return a[1]<b[1];
}
);
int pre = intervals[0][1];
for(int i = 1;i<intervalsNum;i++)
{
if(intervals[i][0]>=pre)
{
pre= intervals[i][1];
counter++;
}
}
return (intervalsNum - counter);
}
};
二、种植花朵(简单)
1. 题解
可以种植的花的地方需要满足
(1)原位置没花;
(2)中间项:种植后相邻两边没有花;
(3)边角项:邻边没有花;
(4)特殊情况:只有一个空花坛。
2. 解题代码
class Solution {
public:
bool canPlaceFlowers(vector<int>& flowerbed, int n) {
int flowerNum = flowerbed.size();
//边界限定:①没有种植花;②只有一个空花坛
if((n == 0) || (flowerNum ==1 && flowerbed[0] == 0)){
return true;
}
for(int i = 0;i < flowerNum; i++)
{
if(flowerbed[i]==0)//若所选花坛为空
{
if(i == 0 ) //如果是最左边的花坛,则仅判断它右边是否有花
{
if(flowerbed[i+1] ==0)
{
flowerbed[i] = 1;
n--;
if(n == 0)
{
return true;
}
}
}
else if(i == (flowerNum - 1))//如果是最右边的花坛,则仅判断它左边是否有花
{
if(flowerbed[i-1] == 0)
{
flowerbed[i] = 1;
n--;
if(n == 0)
{
return true;
}
}
}
else if((flowerbed[i+1] == 0) && (flowerbed[i-1] ==0))//中间则判断两边
{
flowerbed[i] = 1;
n--;
if(n == 0)
{
return true;
}
}
}
}
return false;
}
};
简易写法:
bool canPlaceFlowers(vector<int>& flowerbed, int n) {
if (n == 0)
return true;
for (int i = 0; i < flowerbed.size(); i ++) {
if (flowerbed[i] == 0 && (i == 0 || flowerbed[i - 1] == 0) && (i == flowerbed.size() - 1 || flowerbed[i + 1] == 0)) {
n--;
if (n == 0) return true;
flowerbed[i] = 1;
}
}
return false;
}
法二:
防御式编程思想:在 flowerbed 数组两端各增加一个 0, 这样处理的好处在于不用考虑边界条件,任意位置处只要连续出现三个 0 就可以栽上一棵花
class Solution {
public:
bool canPlaceFlowers(vector<int>& flowerbed, int n) {
flowerbed.insert(flowerbed.begin(),0);
flowerbed.insert(flowerbed.end(),0);
int flowerNum = flowerbed.size();
for (int i = 1; i < (flowerNum-1); i++)
{
if((flowerbed[i-1] == 0)&&(flowerbed[i] == 0) && (flowerbed[i+1] == 0))
{
flowerbed[i] = 1;
n--;
}
}
return n <= 0;
}
};