理论基础
- 455.分发饼干
- 376. 摆动序列
- 53. 最大子序和
贪心算法没有规律?
贪心的实质是每一阶段的局部最优,从而达到全局最优。(所以贪心其实是求最优问题)
难点在于怎么划分局部,以及求得局部最优
可分为四步:(其实还是两步,找出局部最优,然后推导出全局最优)
(1)将问题分解为若干个子问题
(2)找出适合的贪心策略
(3)求解每一个子问题的最优解
(4)将局部最优解堆叠成全局最优解
第一题:分发饼干
首先孩子的胃口值g(i),每个饼干的尺寸s(j),需要满足s(j)>=g(i),才算满足了一个小孩,更可能满足多的小孩,输出得到满足的小孩数量。
分析:大尺寸的饼干可以满足很多的小孩,比如5可以满足12345,尽量让5先满足5,充分利用饼干尺寸,
所以局部最优是大饼干喂给胃口大的,全局最优是尽可能多的小孩被满足
分组示意:
先对两个数组排序,然后从后向前遍历小孩数组,用饼干组的最大值满足小孩组的可以满足的最大值。并统计小孩数量
求局部最优
if(index>=0 && s[index]>=g[i]){
result++;
index--;
}
第二题:摆动序列
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。
例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的。相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
摆动序列:相邻两数之间求差值,要求差值序列在正负之间摆动
利用峰值来检查有无波动
产生子序列之后,让其有最多的局部峰值,删去单调坡度上的节点,然后统计长度。
计算是否有峰值的时候,通过遍历的下标i,计算prediff(nums[i]-nums[i-1])和curdiff(nums[i+1]-nums[i]) ,如果prediff<0 && curdiff>0 或者prediff>0 && curdiff<0此时存在波动
但不是每次都是单调坡,也有平坡
处理情况:
(1)上下坡中有平坡
(2)数组首尾两端
(3)单调坡中有平坡
第三题:最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
- 输入: [-2,1,-3,4,-1,2,1,-5,4]
- 输出: 6
- 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
局部最优:当前“连续和”为负数的时候立即放弃,从下一个元素开始计算“连续和”
全局最优:选取最大的连续和。
而对于假如在第1,2位置上取得最大和,而在3位置上导致连续和为负从而丢失,可以用一个result来记录最大的连续和。
重点是:注意细节.