说实话,初识贪心算法我是一脸懵逼的,没有特定的模板套路,甚至不明白为啥一些生活中常识、逻辑,一些小技巧就算是算法了。
按照卡哥所说:
贪心算法一般分为如下四步:
- 将问题分解为若干个子问题
- 找出适合的贪心策略
- 求解每一个子问题的最优解
- 将局部最优解堆叠成全局最优解
这个四步其实过于理论化了,我们平时在做贪心类的题目 很难去按照这四步去思考,真是有点“鸡肋”。
做题的时候,只要想清楚 局部最优 是什么,如果推导出全局最优,其实就够了。
充分理解每个问题中的技巧才是贪心算法的关键,即取巧。
455.分发饼干
文章链接:代码随想录 (programmercarl.com)
视频链接:贪心算法,你想先喂哪个小孩?| LeetCode:455.分发饼干
如何尽可能用有限的饼干喂给更多的孩子,首先我们思考,一块最大的饼干能喂给任何人,那喂给饭量大的小孩划算还是饭量小的小孩划算,那自然是喂给饭量大的,因为假如最大的喂给了饭量小的,那么第二大的饼干不一定就能满足饭量大的小孩,而反过来,大饼干给大孩子,小饼干也又可能能满足小孩子的需求。
所以要想满足多数孩子,要实现大饼干给大孩子。
知道这一点就简单了,我们可以采用双指针加上一个while循环解决该问题。
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(),g.end());
sort(s.begin(),s.end());
int gright=g.size()-1;
int sright=s.size()-1;
int num=0;
while(sright>=0&&gright>=0)
{
if(g[gright]<=s[sright]){//大饼干给大孩子
num++;
sright--;
gright--;
}
else{
gright--;大饼干也不满足最大的孩子就试试第二大的孩子
}
}
return num;
}
};
376. 摆动序列
文章链接:代码随想录 (programmercarl.com)
视频链接:贪心算法,寻找摆动有细节!| LeetCode:376.摆动序列
一开始省题不清楚,将子序列和子串混肴了,子序列是可以由分开的元素组成的,子串只能以一段连续的元素组成。
这道题需要我们找到最长子序列的长度,那不妨想一下,摆动序列是什么样的。
用图像理解,就是一个点增了,下一个就要减,再下一个就要增,再下一个就要减......
如果是求子序列那就比较容易了,我们可以把递增的一长段都看成一段,递减的一长段都看成一段,数段数不就出来了?那如何通过代码实现这个过程呢,其实就是遇到这种一长段递增递减的就跳过,(相等的也要跳),只存一正一负的。
代码如下:
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if(nums.size()<=1) return nums.size();
int prediff=0;
int curdiff=0;
int result=1;
for(int i=0;i<nums.size()-1;i++)
{
curdiff=nums[i+1]-nums[i];
if((curdiff>0&&prediff<=0)||(curdiff<0&&prediff>=0))
{
result++;
prediff=curdiff;
}
}
return result;
}
};
53. 最大子序和
题目链接:53. 最大子数组和 - 力扣(LeetCode)
文章链接:代码随想录 (programmercarl.com)
视频链接:贪心算法的巧妙需要慢慢体会!LeetCode:53. 最大子序和
贪心算法就是通过题目中的一些小技巧小特点去贪,这道题又该怎么贪呢?
首先我们需要知道,前面一段数的和如果是负数,那么如果加上一个数a,最后结果也一定比a小,所以与其加上前面一大段,不如直接舍弃,从a开始。而如果前面一段数的和是正数,那么加上a后,一定也比a大,就留着。
当然我们也需要用一个变量result去记录我遍历时的产生的最大和
因此代码如下:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int result=INT_MIN;
int sum=0;
for(int i=0;i<nums.size();i++)
{
sum+=nums[i];
if(sum>result) result=sum;
if(sum<0) sum=0;//重置子串起始位置
}
return result;
}
};
Day31打卡成功,第一次接触贪心算法,发现这是一个很灵活的,根据题目的特性而找到最优解的算法,没有固定套路,了解了思路很简单,最难的就是找到该怎么去贪,慢慢琢磨吧!
耗时2.5小时