一、分发小饼干
胃口值:g[1,3,5,7,9]
饼干大小:s[1,3,4,5,8]
① 每颗饼干尽可能满足胃口最大的男孩(大饼干尽量满足大胃口)--推荐
遍历胃口值,每次循环中,无论是否能满足当前,都进入下次循环
② 每个男孩尽可能有一个最小的饼干去满足(小饼干尽量满足小胃口)
遍历小饼干,每次循环中,无论是否能使用当前小饼干,都进入下次循环
二、寻找最大摆动序列
本题不需要删除掉非摆动点,只统计摆动(峰值)点的数量就好,找到最多的局部的峰值就可以找到最长的摆动序列
1. 处理平坡:不仅要使得prediff和curdiff的正负相反,还需要把=0的情况也算上,即if(prediff>=0 && curdiff<0) || (prediff<=0 && curdiff>0)
注意平坡也分两种,一种是“上平平下”,一种是“上平平上”,为了保证每次递增过程或者递减过程只记录一个位,就在每次成功通过判断时更新prediff = curdiff,从而保证在新的方向上,只在最初记录一次,过程如下图所示,在头脑里跑一遍就懂了
2. 处理首末位:对于末位,如[1,2] 可以认为最后一位永远是一个摆动值,那么遍历时不需要再去遍历最后一个元素了。至于首位,在首位之前虚拟一个相等元素,如[1,1,2]让首位得到处理,也就是另prediff初始值为0,即可实现该效果
int wiggleMaxLength(vector<int>& nums) {
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((prediff>=0&&curdiff<0) || (prediff<=0&&curdiff>0))
{
result++;
prediff = curdiff;
}
}
return result;
}
小结:本题对于连续子过程的处理,和首位元素的处理方法非常值得借鉴
三、最大子序和
题目:
nums = [-2,1,-3,4,-1,2,1,-5,4]
遍历该数组,尽可能使得子数组和最大,
当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。从而推出全局最优:选取最大“连续和”
所以,cur_sum值的变化:[-2,1,-2,4,3,5,6,1,5],其中最大值6 即为答案-最大连续和
int maxSubArray(vector<int>& nums) {
int result = INT32_MIN;
int sum=0; // 遍历到每个位置时,计算最大连续和
for(int i=0; i<nums.size(); i++)
{
sum+=nums[i];
result = sum > result ? sum : result; // 始终记录最大连续和
sum = sum < 0 ? 0:sum; // 当连续和为负值,舍弃
}
return result;
}
听说这题可以用动态规划做,留坑