算法训练Day31 | 贪心算法理论基础;LeetCode455.分发饼干;376. 摆动序列;53. 最大子数组和

这篇博客详细讲解了贪心算法的基础理论,并通过LeetCode的3道题目(455. 分发饼干、376. 摆动序列、53. 最大子数组和)进行实战应用。对于每道题目,博主分析了思路,提供了两种不同的代码实现,并进行了复杂度分析,探讨了贪心策略如何保证局部最优转化为全局最优。
摘要由CSDN通过智能技术生成

目录

贪心算法理论基础

 LeetCode455.分发饼干

1. 思路

2. 代码实现

3. 复杂度分析

4. 思考与收获

 LeetCode376. 摆动序列

1. 思路

2. 代码实现

3. 复杂度分析

4. 思考与收获

LeetCode53. 最大子数组和

方法一:暴力解法

方法二:贪心解法

1. 思路

2. 代码实现

3. 复杂度分析

4. 思考与收获


贪心算法理论基础

Referece:代码随想录 (programmercarl.com)

 LeetCode455.分发饼干

 链接:LeetCode455. 455. 分发饼干 - 力扣(LeetCode)

1. 思路

为了满足更多的小孩,就不要造成饼干尺寸的浪费。大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子,那么就应该优先满足胃口大的。

这里的局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩

可以尝试使用贪心策略,先将饼干数组和小孩数组排序。然后从后向前遍历小孩数组,用大饼干优先满足胃口大的,并统计满足小孩数量。 

这个例子可以看出饼干9只有喂给胃口为7的小孩,这样才是整体最优解,并想不出反例,那么就可以写代码了;

2. 代码实现

实现思路1:优先分饼干,给饼干找合适的孩子

局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩;

优先把饼干喂出去,如果饼干满足不了当前的孩子,就换个胃口小的孩子,最后喂出去的饼干个数,就是满足的孩子的数量;

可以采用双指针法,初始都定义在数组的最后一位;然后根据情况向前移动;

# 优先把饼干分出去,把大饼干分给胃口大的
# 如果大饼干满足不了当前的孩子,就找个胃口更小的孩子分
# 最后饼干分出去的数量,就是满足的孩子的个数
# 双指针法+贪心
# time:**max( O(MlogM), O(NlogN) )**;space:O(1)
class Solution(object):
    def findContentChildren(self, g, s):
        """
        :type g: List[int]
        :type s: List[int]
        :rtype: int
        """
        g.sort()
        s.sort()
        child = len(g)-1
        cookie = len(s)-1
        count = 0
        while child>=0 and cookie>=0:
            # 如果当前饼干满足当前孩子
            if s[cookie]>=g[child]:
                count += 1
                cookie -= 1
                child -= 1
            # 如果当前饼干不满足当前孩子,找胃口更小的孩子
            else:
                child -= 1
        return count

也可以这样写,既然是优先分饼干,那就遍历孩子:

有的同学看到要遍历两个数组,就想到用两个for循环,那样逻辑其实就复杂了,可以用一个index来控制饼干数组的遍历,遍历饼干并没有再起一个for循环,而是采用自减的方式,这也是常用的技巧。

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

实现思路2:优先喂饱孩子,给孩子找合适的饼干

局部最优就是小饼干喂给胃口小的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩;

优先把孩子满足,给胃口小的分小饼干,如果当前饼干满足不了当前孩子,就找个更大的饼干给他,最后孩子遍历到的位置,就是可以满足的孩子的数量;

可以采用双指针法,初始都定义在数组的第一位;然后根据情况向后移动;

# 优先把孩子满足,把小饼干分给胃口小的
# 如果当前饼干满足不了当前的孩子,就找个更大的饼干给他
# 最后孩子遍历到的位置,就是可以满足的孩子的数量
# 双指针法+贪心
# time:**max( O(MlogM), O(NlogN) )**;space:O(1)
  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值