代码随想录算法训练营Day31 | 贪心算法(1/6) 贪心算法理论基础 LeetCode 455.分发饼干 376. 摆动序列 53. 最大子序和

本文介绍了贪心算法的理论基础,包括其本质是选择局部最优以达全局最优,以及适用场景和一般解题步骤。同时给出了三道LeetCode练习题,如455题分饼干、376题摆动子序列、53题最大子数组和,并分别阐述了解题思路。

1. 贪心算法理论基础

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

1.1 什么时候用贪心

贪心没有固定的套路,当一道题可以由局部最优推算出整体最优的时候,就可以用贪心。

1.2 贪心的一般解题步骤

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

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

步骤有些琐碎,实际做题不会这么详细的去构思

2. 练习题

第一题

455. Assign Cookies

Assume you are an awesome parent and want to give your children some cookies. But, you should give each child at most one cookie.

Each child i has a greed factor g[i], which is the minimum size of a cookie that the child will be content with; and each cookie j has a size s[j]. If s[j] >= g[i], we can assign the cookie j to the child i, and the child i will be content. Your goal is to maximize the number of your content children and output the maximum number.

大饼干既能满足贪婪高的小孩,也能满足贪婪低的小孩,但是小饼干只能满足贪婪低的小孩,因此要优先把大的分给贪婪高的小孩,避免浪费大饼干。

所以要从后向前来遍历饼干和小孩。

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        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
第二题

376. Wiggle Subsequence

wiggle sequence is a sequence where the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with one element and a sequence with two non-equal elements are trivially wiggle sequences.

  • For example, [1, 7, 4, 9, 2, 5] is a wiggle sequence because the differences (6, -3, 5, -7, 3) alternate between positive and negative.
  • In contrast, [1, 4, 7, 2, 5] and [1, 7, 4, 5, 5] are not wiggle sequences. The first is not because its first two differences are positive, and the second is not because its last difference is zero.

subsequence is obtained by deleting some elements (possibly zero) from the original sequence, leaving the remaining elements in their original order.

Given an integer array nums, return the length of the longest wiggle subsequence of nums.

乍一看很麻烦,因为又要剔除无关元素,又要求出符合条件的最大长度。但实际上不需要对数组进行什么in place的操作,只是统计一下符合要求的长度即可。

可以用两个变量:curDiff 和 preDiff来计算当前数组中元素与前后数的差值。

class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        if len(nums)<= 1:
            return len(nums)
        curDiff = 0  # current
        preDiff = 0  # previous 
        result = 1  
        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. Maximum Subarray

Given an integer array nums, find the subarray with the largest sum, and return its sum.

先设置一个无穷小的数当起点,然后不断累加列表中的数,同时进行比较,遇到比较大的数就给了result,当累加完这次,数值变成负的就重置为0,避免对结果造成影响。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值