代码随想录 Day 32 |【第八章 贪心算法 part 01】理论基础、455.分发饼干、376. 摆动序列、53. 最大子序和

一、理论基础

1. 什么是贪心

贪心的本质是选择每一阶段的局部最优,从而达到全局最优。

2. 贪心的解题步骤

  • 将问题分解为若干个子问题
  • 找出适合的贪心策略
  • 求解每一个子问题的最优解
  • 将局部最优解堆叠成全局最优解

二、455.分发饼干

1. 解题思路

尽量用最大的饼干去满足胃口大的孩子。

2. 代码实现

(1)因为是用大饼干满足胃口大的孩子,所以对饼干、孩子胃口数组排序。定义一个result变量,用于记录喂饱了多少个小孩。

(2)从大到小遍历(从后向前遍历):接下来用while去控制饼干的从大到小遍历,每一个饼干需要从大到小投喂给某一个孩子,所以如果投喂不了某个孩子,孩子胃口数组会继续向前遍历,而饼干不动,因此只能使用while循环而不是for循环。while循环条件是index>=0(防止抛出异常)并且饼干大于等于孩子胃口时,result才做加1,然后index减1,向前移动一位。

(3)最后返回result。

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        result = 0
        g.sort()
        s.sort()
        j = len(s) - 1
        for i in range(len(g)-1, -1, -1):
            if j >= 0 and s[j] >= g[i]:
                result += 1
                j -= 1
        return result

3. 常见误区

外层必须遍历胃口,内层饼干,不可以颠倒。

因为外层是饼干而里层是胃口的话,那么饼干会一直向前走,而胃口是动态移动的,饼干一直喂不了,会前移,而胃口会一直停在末尾不动,最后饼干结束了,result等于0。

三、376. 摆动序列

代码实现

(1)如果nums的大小等于1,那么直接返回1即可。

(2)定义变量prediff初始为0;curdiff也初始为0;result默认为1,因为默认最右端有一个坡度。

(3)for循环,注意 i 不用遍历到最后一个元素,因为已经默认有一个坡度,所以 i 只需要遍历到nums长度-2的位置。

        curdiff等于nums[i+1]减去nums[i],即后一个元素减去当前元素。接下来判断是否出现波动,1)如果prediff大于等于0,同时curdiff小于0;

2)或如果prediff小于等于0,同时curdiff大于0;

那么满足上述两种情况任一情况都属于出现波动,所以此时result加1。

(4)使用完成curdiff后,就用curdiff指向prediff。

(5)注意:以上代码忽略了单调平坡的情况,所以需要更改代码(4),原本代码 (4)是使prediff紧跟curdiff,将其修改为当出现摆动才去修改prediff的位置,将(4)放在if下方,这样才可以绕过单调有平坡的情况。

class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        if len(nums) <= 1:
            return len(nums)
        result = 1
        curdiff = 0
        prediff = 0
        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. 最大子序和

1. 解题思路

        当连续和为负数时,就抛弃连续和,从下一个位置作为起点寻找连续和最大的子序列。注意不是说遇到负数就抛弃连续和,而是说遇到连续和为负数才抛弃当前连续和。

2. 代码实现

(1)定义一个变量result 用于记录连续和中的最大值,所以要初始化为一个最小值。定义count用于更新连续和,初始化为0。

(2)for循环遍历数组,所以连续和数组count进行累加;如果count大于result,那么将result进行更新;当count小于0时,就将count更新为0,从下一个新位置开始累加连续和。

(3)最后返回result即可。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值