前言
更详细的在大佬的代码随想录 (programmercarl.com)
本系列仅是简洁版笔记,为了之后方便观看
本质
局部最优推出全局最优
验证
验证可不可以用贪心算法最好用的策略就是举反例,想不到反例就试贪心
分发饼干
455. 分发饼干 - 力扣(LeetCode)
思考
1.贪心策略:大饼干满足大胃口/优先用小饼干
2.if语句的顺序不能变,如果变了,可能会抛异常
if (index >= 0 && s[index] >= g[i])
3.for 控制胃口,for循环里面的if控制饼干,如果调换顺序,胃口可能持续不动
代码
class Solution {
public:int findContentChildren(vector<int>& g, vector<int>& s) {//g是胃口,s是饼干sort(g.begin(), g.end());sort(s.begin(), s.end());int index=s.size()-1;int result = 0;for(int i=g.size()-1;i>=0;i--){if(index>=0&&s[index]>=g[i]){index--;result++;}}return result;}
};
摆动序列
376. 摆动序列 - 力扣(LeetCode)
思考
删掉单调坡上的元素,保留峰值元素
不需要陷入删除细节,只需要统计数组的峰值数量
情况
1.上下坡有平坡(从而在条件中添加prediff == 0 )
(preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)
2.首尾元素(数组中有两个元素的时候摆动也是2,可以看成延长前面的元素例如【1,0】变成【1,1,0】,从而转到情况1)
3.单调坡度有平坡(prediff只记录当摆动处出现时下一个坡的初始的坡度,这就是prediff=curdifff写在if语句里面跟着result变化的原因)
代码
class Solution {
public:int wiggleMaxLength(vector<int>& nums) {if(nums.size()<=1) return nums.size();int curDiff=0;//当前的差值int preDiff=0;//之前的差值int result=1;//序列默认序列最右边有一个峰值for(int i=0;i<nums.size()-1;i++){curDiff=nums[i+1]-nums[i];if((preDiff<=0&&curDiff>0)||(preDiff >= 0 && curDiff < 0)){//峰值两侧符号不同result++;preDiff = curDiff;}}return result;}
};
最大子序和
53. 最大子数组和 - 力扣(LeetCode)
局部最优:抛弃连续和是负数的情况
class Solution {
public:int maxSubArray(vector<int>& nums) {int result = INT32_MIN;int cnt=0;for(int i=0;i<nums.size();i++){cnt+=nums[i];if(cnt>result){result=cnt;}if(cnt<=0){cnt=0;}}return result;}
};
买卖股票最佳时机II
思路:
分解利润
第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。
相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])
局部最优:只收获每天的正利润
class Solution {
public:int maxProfit(vector<int>& prices) {int result = 0;for (int i = 1; i < prices.size(); i++) {result += max(prices[i] - prices[i - 1], 0);}return result;}
};
跳跃游戏
关键:不是如何跳跃,而是覆盖范围,观察最后覆盖范围有没有到终点
cover = max(i + nums[i], cover)
代码
class Solution {
public:bool canJump(vector<int>& nums) {int cover = 0;if (nums.size() == 1) return true; //考虑特殊情况for (int i = 0; i <= cover; i++) { cover = max(i + nums[i], cover);if (cover >= nums.size() - 1) return true; // 说明覆盖范围可以覆盖到终点}return false;}
};