代码随想录算法训练营第二十七天 |贪心算法part01

85 阅读2分钟

代码随想录算法训练营第二十七天 |贪心算法part01

理论基础

找到每个阶段的局部最优,从而去推导全局最优

只要想清楚 局部最优 是什么,如果推导出全局最优,其实就够了。

贪心的两个极端

1 常识性的东西 直接会想到

2 究竟是怎么想到的

贪心的套路

贪心无套路

想清楚每个阶段的局部最优解是什么,能不能推出全局最优。

455 分发饼干

image.png 需要注意:遍历的是饼干,而不是孩子,把饼干分给孩子。另外需要注意判断条件,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 摆动序列

image.png 思路:原地删除,那我们就原地移动。

记录一下当前的差值 和 之前的差值,如果异号说明满足条件,如果不是异号,那么就继续往后走,依旧保留之前的差值,用来对比之后的差值。

只有异号发生的时候,我们才需要进行之前的差值的更换

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 最大子序和

image.png

思路:这个题和上一个的区别就是变成连续的了,上一个是可以进行移动,这一个需要整体移动了。

暴力法代码:两个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)