理论基础
贪心的本质是选择每一阶段的局部最优,从而达到全局最优
贪心算法没有固定的套路,手动模拟一下可以从局部最优推出整体最优,而且想不出反例,那就试一试贪心。严格的数学证明比较复杂,暂不考虑
贪心算法一般分为如下四步:
- 将问题分解为若干个子问题
- 找出适合的贪心策略
- 求解每一个子问题的最优解
- 将局部最优解堆叠成全局最优解
455.分发饼干
大饼干满足大胃口,倒序遍历。
如何确定for循环的是胃口还是饼干?
如果for循环的是饼干,当前的胃口大于饼干,不满足条件,则饼干会走到更小值,更不会满足条件,但实际是有更小胃口的可能被满足,因此出现错误
如果for循环的是胃口,当前的胃口大于饼干,不满足条件,此时的饼干是最大的,这个胃口以后不可能被满足,因此胃口继续往小的走,寻找可能被这个最大饼干满足的胃口
class Solution:
def findContentChildren(self, g: List[int], s: List[int]) -> int:
g.sort()
s.sort()
result = 0
index = len(s) - 1
for i in range(len(g)-1, -1, -1):
if index >= 0 and g[i] <= s[index]:
result += 1
index -= 1
return result
376. 摆动序列
要考虑的情况比较多
- 上下坡中有平坡
- 首尾元素
- 单调坡中有平坡
代码很简单,但是考虑的东西并不少,得多学习
class Solution:
def wiggleMaxLength(self, nums: List[int]) -> int:
prediff = 0
result = 1
for i in range(len(nums)-1):
curdiff = nums[i+1] - nums[i]
if (prediff >= 0 and curdiff < 0) or (prediff <= 0 and curdiff > 0):
result += 1
prediff = curdiff
return result
53. 最大子序和
如果当前值之和为负数,那么直接舍弃,因为负数会拉低后面的数
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
result = float('-inf')
count = 0
for num in nums:
count += num
result = max(result, count)
if count <= 0:
count = 0
return result