2023-12-29 贪心算法 分发饼干和摆动序列以及最大子数组和

贪心算法

什么是贪心算法?

就是每一阶段的最优解,从局部的最优解达到全局的最优解!
最好用的策略就是举反例,如果想不到反例,那么就试一试贪心吧

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

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

455. 分发饼干

思路:这类涉及列表的数据!可以先考虑对列表进行排序先!然后优先满足最小胃口的或者排序优先满足最大胃口的都可以!

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

python 复制代码
class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        s.sort()
        g.sort()
        count = 0
        sum = 0
        for _g in g:
            while sum < len(s):
                if _g <= s[sum]:
                    count += 1
                    s[sum] = -1
                    break
                sum += 1
        return count
    
class Solution:
    def findContentChildren(self, g, s):
        g.sort()  # 将孩子的贪心因子排序
        s.sort()  # 将饼干的尺寸排序
        index = 0
        for i in range(len(s)):  # 遍历饼干
            if index < len(g) and g[index] <= s[i]:  # 如果当前孩子的贪心因子小于等于当前饼干尺寸
                index += 1  # 满足一个孩子,指向下一个孩子
        return index  # 返回满足的孩子数目
            

376. 摆动序列

思路:理解题目,一上一下就是产生峰值就是摆动了!这就是贪心所贪的地方,让峰值尽可能的保持峰值,然后删除单一坡度上的节点
python 复制代码
class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int: 
        if len(nums) <= 1:
            return len(nums)
        pre_diff = 0	#前一对元素的差值	
        cur_diff = 0	#当前一对元素的差值
        count = 1	# 记录峰值
        for i in range(len(nums) - 1):
            cur_diff = nums[i + 1] -nums[i]
            if (pre_diff >= 0 and cur_diff < 0) or (pre_diff <= 0 and cur_diff > 0):
                count += 1
                pre_diff = cur_diff
        return count 
            

53. 最大子数组和

思路:关键点是,每次的比较叠加的和不能小于0,否则不如当前的数大了!还有使用额外列表来做的思想也很精妙!关键点也是大于0这一点!
python 复制代码
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        # 使用额外列表来解决
        dp = [0] * len(nums)
        dp[0] = nums[0]
        for i in range(1, len(nums)):
            if dp[i - 1] > 0:  
                dp[i] = dp[i - 1] + nums[i]
            else:
                dp[i] = nums[i]
        return max(dp)
    def maxSubArray1(self, nums: List[int]) -> int:
        # 使用滑动窗口来解决 关键点就是每次比较的和知否大于当前的数值
        cur = nums[0]
        temp = 0
        for _num in nums:
            temp += _num
            # 如果临时值大于当前窗口的最大值 重新赋值
            if temp > cur:
                cur = temp
            # 如果不小于0的哇,怎么累加都不会小于刚加的那个值了!
            if temp < 0:
                temp = 0
        return cur
相关推荐
断剑zou天涯1 小时前
【算法笔记】有序表——SB树
笔记·算法
曾几何时`1 小时前
滑动窗口(十五)2962. 统计最大元素出现至少 K 次的子数组(越长越合法型)
数据结构·算法
究极无敌暴龙战神X2 小时前
机器学习相关
人工智能·算法·机器学习
断剑zou天涯2 小时前
【算法笔记】有序表——跳表
笔记·算法
挖矿大亨2 小时前
c++中的函数调用运算符重载
前端·c++·算法
wadesir2 小时前
Rust语言BM算法实现(从零开始掌握Boyer-Moore字符串搜索算法)
算法·rust·.net
硅农深芯2 小时前
深入解析 AECQ100 标准中的 Cpk:保障汽车电子元器件质量的关键指标
人工智能·算法·汽车·芯片·cpk
AI 菌2 小时前
Qwen-Image:复杂文本渲染与精准图像编辑的图像生成基础模型
人工智能·算法·计算机视觉·大模型·千问
Cx330❀2 小时前
《C++ 递归、搜索与回溯》第1题:汉诺塔问题
开发语言·c++·算法·面试·回归算法
爱学习的uu2 小时前
大模型学习1——各类模型接入langchain,模型调用,记忆管理,工具调用
人工智能·python·深度学习·学习·算法·机器学习·langchain