目录
一、455. 分发饼干
二、376. 摆动序列
三、53. 最大子数组和
贪心理论:模拟感觉可以局部最优推出整体最优,而且想不到反例,那么就试一试贪心。
一、455. 分发饼干
题目链接:力扣
文章讲解:代码随想录
视频讲解:
题目:
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。
对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
代码:
class Solution {
public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int count = 0;for(int biscuits = s.size()-1, child = g.size()-1; biscuits >= 0 && child >= 0; child--){if(s[biscuits] >= g[child]){biscuits--;count++;}}return count;}
};
时间复杂度: O(mlogm+nlogn) 空间复杂度O(logm+logn)
⏲:2:47
总结:局部最优--小尺寸的饼干优先给小胃口的小孩,小胃口满足不了大胃口也满足不了,全局最优--小胃口都喂饱,饼干剩余部分为小胃口满足不了的,小孩剩余部分每个人胃口都比已满足的人大。
二、376. 摆动序列
题目链接:力扣
文章讲解:代码随想录
视频讲解:
题目:如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如, [1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。 相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。 子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。 给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 。
代码:
class Solution {
public:int wiggleMaxLength(vector<int>& nums) {//根据峰值判断if (nums.size() < 2) return nums.size();int prediff = nums[1] - nums[0];int ans = prediff != 0 ? 2 : 1;for (int i = 2; i < nums.size(); i++){int diff = nums[i] - nums[i-1];if((diff > 0 && prediff <= 0) || (diff < 0 && prediff >= 0)){ans++;prediff = diff;}}return ans;//用新数组重新构造摆动序列/*vector<int> new_nums;int judge = -1;new_nums.push_back(nums[0]);for(int i = 1; i < nums.size(); i++){if(nums[i] > nums[i-1]){if(judge == 1){while(judge == 1 && i < nums.size()-1){i++;if(nums[i] < nums[i-1]) judge = 0;}new_nums.pop_back();if (judge == 1){new_nums.push_back(nums[i]);return new_nums.size();}new_nums.push_back(nums[i-1]);new_nums.push_back(nums[i]);}else{judge = 1;new_nums.push_back(nums[i]);}}else if(nums[i] < nums[i-1]){if(judge == 0){while(judge == 0 && i < nums.size()-1){i++;if(nums[i] > nums[i-1]) judge = 1;}new_nums.pop_back();if (judge == 0){new_nums.push_back(nums[i]);return new_nums.size();}new_nums.push_back(nums[i-1]);new_nums.push_back(nums[i]);}else{judge = 0;new_nums.push_back(nums[i]);}}}return new_nums.size();*/
}
};
时间复杂度: O(n) 空间复杂度O(1)
⏲:19:20
总结:局部最优--峰与谷,全局最优--只有峰与谷。难点 1.峰与谷的转换:差值大于0和小于0。2.第一个峰还是谷与平坡的情况:通过predif的更新位置保障平坡的判断只可能在第一次中出现。
三、53. 最大子数组和
题目链接:力扣
文章讲解:代码随想录
视频讲解:
题目:如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如, [1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。 相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。 子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。 给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 。
代码:
class Solution {
public:int maxSubArray(vector<int>& nums) {int ans = nums[0];int sum = nums[0];for(int fast = 1; fast < nums.size(); fast++){sum = max(nums[fast], sum+nums[fast]);if(sum > ans) ans = sum;}return ans;}
};
时间复杂度: O(n) 空间复杂度O(1)
⏲:17:55
总结:局部最优--连续相加的数,或者最大的数本身。