代码随想录算法训练营第三十一天 | 贪心算法 part 1 | 455.分发饼干、376. 摆动序列、53. 最大子序和

贪心理论基础

贪心的本质就是,局部最优可以达到全局最优。将问题分解成小问题,小问题寻找最优解,结合一起就是全局最优解。

所以贪心算法的使用条件:

  • 贪心选择性质:只有当局部最优选择始终可以导致全局最优解时,贪心算法才能保证得到最优解。
  • 最优子结构:原问题的最优解包含子问题的最优解。

455.分发饼干

Leetcode

在这里插入图片描述

思路

小饼干先喂饱胃口小的小孩。全局最优就是喂饱尽可能多的小孩。

代码

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        count = 0
        g.sort()
        s.sort()
        pointer = 0

        for cookie in s:
            if pointer == len(g):
                break
            if cookie >= g[pointer]:
                pointer += 1
                count += 1

        return count

复杂度分析

  • 时间复杂度:O(nlogn), 排序
  • 空间复杂度:O(1)

376. 摆动序列

Leetcode

在这里插入图片描述

思路

只看局部峰值,从而达到最长摆动序列。
在这里插入图片描述
有三种情况:

情况一:上下坡中有平坡
情况二:数组首尾两端
情况三:单调坡中有平坡

我们使用prediff和curdiff来判断是否有摆动。

代码

class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        prediff = 0
        curdiff = 0
        res = 1
        for i in range(len(nums) - 1):
            curdiff = nums[i+1] - nums[i]
            if prediff * curdiff <= 0 and curdiff != 0:
                res += 1
                prediff = curdiff

        return res

复杂度分析

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

53. 最大子序和

Leetcode

在这里插入图片描述

思路

遍历 nums,从头开始用 count 累积,如果 count 一旦加上 nums[i]变为负数,那么就应该从 nums[i+1]开始从 0 累积 count 了,因为已经变为负数的 count,只会拖累总和。

代码

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        res = nums[0]
        temp = 0

        for n in nums:
            if temp <= 0:
                temp = 0
            temp += n
            res = max(res, temp)

        return res

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
第二十二算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值