@代码随想录算法训练营第31天 | 贪心算法理论基础,LeetCode455.分发饼干,376. 摆动序列,53. 最大子序和
贪心算法理论基础
其实没有理论基础,硬要总结的话就是“可以使用贪心算法的前提:局部最优的堆叠可以得到全局最优!”
455.分发饼干
第一遍读题思考
大的饼干给胃口大的是局部最优,那这样是不是就可以导致全局最优了呢(即分给尽可能多的小朋友),想不出反例,所以就这么干。
代码随想录解法思路
一样的。
c++代码具体实现注意事项
(递归版本)
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int count{0};
int i=s.size()-1;
int j=g.size()-1;
while(i>=0 && j>=0){
if(s[i]>=g[j]){
count++;
i--;
j--;
continue;
}
j--;
}
return count;
}
};
376. 摆动序列
第一遍读题思考
注意:子序列可以是不连续的。
代码随想录解法思路
根据一个点的pre_diff和cur_diff来判断是否选取这个点。关键在于判断峰值。
c++代码具体实现注意事项
代码随想录的思路懒得看所以自己总结了下面的判断条件:
指针每次移动都更新cur_diff
- 左右差乘积小于0,用cur_diff更新pre_diff并且有效点数加1.
- 左右差乘积等于0,如果不是右差等于0,则按照上一步更新。否则都不更新。
- 如果乘积大于0,只更新pre_diff,count不加1
- 如果指针指向最后一个数字,直接count加1(为什么可以这样?因为第二步中只在右差不等于0的时候加1,所以即便第二个数字和最后一个相同也没关系。)
(递归版本)
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if(nums.size()==1) return 1;
if(nums.size()==2 && nums[0]==nums[1]) return 1;
else if(nums.size()==2 && nums[0]!=nums[1]) return 2;
int pre_diff = nums[1] - nums[0];
int cur_diff{0};
int count;
if(pre_diff==0) count=0;
else count=1;
for(int i=1;i<nums.size();i++){
if(i!=nums.size()-1){
cur_diff = nums[i+1]-nums[i];
if(cur_diff*pre_diff<0){
pre_diff = cur_diff;
count++;
}
else if(cur_diff*pre_diff==0){
if(cur_diff!=0){
pre_diff = cur_diff;
count++;
}
}
else{
pre_diff = cur_diff;
}
}
else{
count++;
}
}
return count;
}
};
53. 最大子序和
第一遍读题思考
子数组要连续,并且根据题目条件来看数组里是有负数的。
如果把负数想成断点,用一个maxvalue来记录result,用sum来记录当前快慢指针之间的和,慢指针先指向0位置,快指针向前遍历,遇到正数就更新sum和maxvalue,遇到负数就把慢指针放到快指针的位置,并且sum归0,直到快指针指向最后一位。
代码随想录解法思路
上面的思路问题在于遇到负数就抛弃前面的所有数字,这是不对的。看看代码随想录的思路。
重点在于什么时候放弃,应该是在连续和为负数的时候再放弃前面的.
c++代码具体实现注意事项
非常关键的问题在于sum加加之后就应该与maxValue进行比较赋值,然后才对sum进行判断,想象看如果把for循环中的两个if调换顺序在什么情况下会失效??([-1,-2] or [-2,-1])
(递归版本)
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.size()==1) return nums[0];
int maxValue{-INT_MAX};
int sum{0};
for(int i=0;i<nums.size();i++){
sum+=nums[i];
if(sum>maxValue){
maxValue = sum;
}
if(sum<0) sum = 0;
}
return maxValue;
}
};