代码随想录算法训练营第二十七天 |贪心算法part01
理论基础
找到每个阶段的局部最优,从而去推导全局最优
只要想清楚 局部最优 是什么,如果推导出全局最优,其实就够了。
贪心的两个极端
1 常识性的东西 直接会想到
2 究竟是怎么想到的
贪心的套路
贪心无套路
想清楚每个阶段的局部最优解是什么,能不能推出全局最优。
455 分发饼干
需要注意:遍历的是饼干,而不是孩子,把饼干分给孩子。另外需要注意判断条件,index对应的是到第几个孩子了,所以index需要小于孩子的数量。
def findContentChildren(self, g, s):
g.sort() # 将孩子的贪心因子排序
s.sort() # 将饼干的尺寸排序
index = 0
for i in range(len(s)): # 遍历饼干
if index < len(g) and g[index] <= s[i]: # 如果当前孩子的贪心因子小于等于当前饼干尺寸
index += 1 # 满足一个孩子,指向下一个孩子
return index # 返回满足的孩子数目
376 摆动序列
思路:原地删除,那我们就原地移动。
记录一下当前的差值 和 之前的差值,如果异号说明满足条件,如果不是异号,那么就继续往后走,依旧保留之前的差值,用来对比之后的差值。
只有异号发生的时候,我们才需要进行之前的差值的更换
result = 1
prediff = 0
curdiff = 0
for i in range(len(nums) - 1):
curdiff = nums[i] - nums[i+1]
if curdiff * prediff <= 0 and curdiff != 0:
result += 1
prediff = curdiff
return result
53 最大子序和
思路:这个题和上一个的区别就是变成连续的了,上一个是可以进行移动,这一个需要整体移动了。
暴力法代码:两个for循环进行遍历,保存最大的和。过不去。
nums = [-2,1,-3,4,-1,2,1,-5,4]
result = float('-inf')
sum_ = 0
for i in range(len(nums)):
sum_ = 0
for j in range(i,len(nums)):
sum_ += nums[j]
result = max(sum_,result)
print(result)
贪心算法:
局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。
全局最优:选取最大“连续和”
nums = [-2,1,-3,4,-1,2,1,-5,4]
result = float('-inf')
sum_ = 0
for i in range(len(nums)):
sum_ += nums[i]
if sum_ > result:
result = sum_
if sum_ <= 0:
sum_ = 0
print(result)