day27-greedy-part01-7.29

tasks for today:

1.理论基础

2.455.分发饼干

3.376.摆动序列

4.53.最大子序和

------------------------------------------------------------------

1.理论基础

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

经常与贪心算法放在一起进行比较的就是动态规划,以下是一个例子:

例如,有一堆钞票,你可以拿走十张,如果想达到最大的金额,你要怎么拿?

指定每次拿最大的,最终结果就是拿走最大数额的钱。

每次拿最大的就是局部最优,最后拿走最大数额的钱就是推出全局最优。

再举一个例子如果是 有一堆盒子,你有一个背包体积为n,如何把背包尽可能装满,如果还每次选最大的盒子,就不行了。这时候就需要动态规划。

(2)贪心算法并没有固定的套路, 唯一的难点就是如何通过局部最优,推出整体最优。

那么如何能看出局部最优是否能推出整体最优呢?有没有什么固定策略或者套路呢?也没有!

靠自己手动模拟,如果模拟可行,就可以试一试贪心策略,如果不可行,可能需要动态规划。

(3)如何验证可不可以用贪心算法呢

最好用的策略就是举反例,如果想不到反例,那么就可试一试贪心算法

手动模拟一下感觉可以局部最优推出整体最优,而且想不到反例,那么就试一试贪心

(4)贪心算法一般分为如下四步:

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

2.455.分发饼干

In this practice, teh greedy idea is to use the smallest snack to go through the kids' appetite. Before the operation, both the snack and the kids should be sorted, and the additinal index lists should be used to control the left kids.

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        g.sort()
        s.sort()
        result = 0
        index_kid = list(range(len(g)))

        for snack in s:
            # print('snack', snack)
            for j in index_kid:
                # print('kid', g[j])
                if snack >= g[j]:
                    result += 1
                    index_kid.pop(index_kid.index(j))
                    break
        
        return result

There is another valid mindset is, use the largest snack to satisfy the biggest appetite.

3.376.摆动序列

In this practice, the key idea is to count the number of local maxmium.

One point need to be paied attention to is the special circumstance.

Another is when to update "prediff", the answer is only if the peek shows up, otherwise, the prediff will not be updated.

Only the curdiff is updated iteratively.

class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        if len(nums) <= 1: return len(nums)
        if len(nums) == 2 and nums[0] != nums[1]: return 2
        elif len(nums) == 2 and nums[0] == nums[1]: return 1

        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

4.53.最大子序和

Apart from raw search, the greedy method is reflected on the update of count. For the record, the update of results only happens when count is greater than current result. This may be a little tricky to understand especially when all the elemnts are negetive, but if you do a few steps simulation, the result is still correct.

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

  • 18
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值