代码随想录算法训练营Day31 | 贪心算法理论基础、455.分发饼干、376. 摆动序列、53. 最大子序和 | Python | 个人记录向

贪心算法理论基础

代码随想录:贪心算法理论基础

455.分发饼干

代码随想录:455.分发饼干
Leetcode:455.分发饼干

做题

将饼干和小孩都按降序排序,再依次满足。

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        g.sort(reverse=True)
        s.sort(reverse=True)
        res = 0
        i = j = 0
        if len(s) == 0 or len(g) == 0:
            return 0
        while i < len(s):
            if s[i] >= g[j]:
                res += 1
                i += 1
            j += 1
            if j >= len(g):
                break
        return res

看文章

大饼干优先

class Solution:
    def findContentChildren(self, g, s):
        g.sort()  # 将孩子的贪心因子排序
        s.sort()  # 将饼干的尺寸排序
        index = len(s) - 1  # 饼干数组的下标,从最后一个饼干开始
        result = 0  # 满足孩子的数量
        for i in range(len(g)-1, -1, -1):  # 遍历胃口,从最后一个孩子开始
            if index >= 0 and s[index] >= g[i]:  # 遍历饼干
                result += 1
                index -= 1
        return result

时间复杂度:O(nlogn)
空间复杂度:O(1)

小饼干优先

class Solution:
    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  # 返回满足的孩子数目

时间复杂度:O(nlogn)
空间复杂度:O(1)

376. 摆动序列

代码随想录:376. 摆动序列
Leetcode:376. 摆动序列

做题

有初始思路,比较简单,需要调试解决特殊情况。用一个bool变量来记录前面是上升还是下降,当bool变化时就res += 1,当前面平峰时需要特殊处理。具体代码如下:

class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        size = len(nums)
        if size == 1: return 1
        if size == 2:
            if nums[0] != nums[1]:
                return 2
            else:
                return 1
        res = 1
        level = True
        for i in range(1, size):
            cur = nums[i] - nums[i-1]
            if i == 1:
                if cur > 0:
                    is_lift = True
                    level = False
                    res += 1
                elif cur < 0:
                    is_lift = False
                    level = False
                    res += 1
            else:
                if level and cur > 0:
                    level = False
                    is_lift = True
                    res += 1
                elif level and cur < 0:
                    level = False
                    is_lift = False
                    res += 1
                elif level:
                    continue
                elif is_lift and cur < 0:
                    res += 1
                    is_lift = False
                elif not is_lift and cur > 0:
                    res += 1
                    is_lift = True

        return res

时间复杂度:O(n)
空间复杂度:O(1)

看文章

计算prediff和curdiff,考虑三种情况:上下坡中有平坡、数组首尾两端、单调坡中有平坡。具体思路看文章。也可以用动态规划。这里感觉太繁琐了,暂时不看。

53. 最大子序和

代码随想录:53. 最大子序和
Leetcode:53. 最大子序和

做题

无贪心算法思路。

看文章

暴力求解

C++可能能过,其他语言不一定
时间复杂度:O(n^2)
空间复杂度:O(1)

贪婪算法

局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。
全局最优:选取最大“连续和”。
局部最优的情况下,并记录最大的“连续和”,可以推出全局最优。
从代码角度上来讲:遍历 nums,从头开始用 count 累积,如果 count 一旦加上 nums[i]变为负数,那么就应该从 nums[i+1]开始从 0 累积 count 了,因为已经变为负数的 count,只会拖累总和。
时间复杂度:O(n)
空间复杂度:O(1)
按照思路自己实现了代码:

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        res = float('-inf')
        cur = 0
        for i in range(len(nums)):
            cur += nums[i]
            res = max(cur, res)
            if cur < 0:
                cur = 0
        return res

以往忽略的知识点小结

  • 贪心算法没什么“思路”,可能就是用简单的思路尝试,然后不断调试,处理特殊情况

个人体会

完成时间:1h40min。
心得:贪心算法比较没“思路”,但特殊情况分析还挺麻烦的,最好自己尝试,看文章有点难进入思路。

  • 25
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值