贪心算法相关题目

1. 什么是贪心?

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

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

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

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

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

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

做题的时候,只要想清楚 局部最优 是什么,如果推导出全局最优,其实就够了。

2. 分发饼干

题目:
在这里插入图片描述
思路:
大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子,那么就应该优先满足胃口大的。

这里的局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。
在这里插入图片描述
代码:

class Solution:
    def findContentChildren(self, g, s):
        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

3. 摆动序列

题目:
在这里插入图片描述
思路:
本题要考虑三种情况:

情况一:上下坡中有平坡
情况二:数组首尾两端
情况三:单调坡中有平坡
记录峰值的条件应该是: (preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)
代码:

class Solution:
    def wiggleMaxLength(self, nums):
        if len(nums) <= 1:
            return len(nums)  # 如果数组长度为0或1,则返回数组长度
        curDiff = 0  # 当前一对元素的差值
        preDiff = 0  # 前一对元素的差值
        result = 1  # 记录峰值的个数,初始为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  # 峰值个数加1
                preDiff = curDiff  # 注意这里,只在摆动变化的时候更新preDiff
        return result  # 返回最长摆动子序列的长度

4. 最大子数组和

题目:
在这里插入图片描述
思路:
采用贪心策略,如果 -2 1 在一起,计算起点的时候,一定是从 1 开始计算,因为负数只会拉低总和,这就是贪心贪的地方!

局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。

全局最优:选取最大“连续和”
代码:

class Solution:
    def maxSubArray(self, nums):
        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

5. 买卖股票的最佳时机 II

题目:
在这里插入图片描述
思路:
采用贪心策略,局部最优:收集每天的正利润,全局最优:求得最大利润。
在这里插入图片描述
代码:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        result = 0
        num = 0
        for i in range(len(prices) - 1):
            num = prices[i + 1] - prices[i]
            if num > 0:
                result += num
        return result

6. 跳跃游戏

题目:
在这里插入图片描述
思路:
贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。
代码:

class Solution:
    def canJump(self, nums: List[int]) -> bool:
        cover = 0
        if len(nums) == 1: return True
        i = 0
        # python不支持动态修改for循环中变量,使用while循环代替
        while i <= cover:
            cover = max(i + nums[i], cover)
            if cover >= len(nums) - 1: return True
            i += 1
        return False

相关推荐

  1. 贪心算法相关

    2024-03-24 09:46:02       43 阅读
  2. 代码随想录 贪心算法-简单题目

    2024-03-24 09:46:02       36 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-24 09:46:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-24 09:46:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-24 09:46:02       82 阅读
  4. Python语言-面向对象

    2024-03-24 09:46:02       91 阅读

热门阅读

  1. 如何在OpenCV中实现实时人脸识别?

    2024-03-24 09:46:02       38 阅读
  2. 24计算机考研调剂 | 江西理工大学

    2024-03-24 09:46:02       41 阅读
  3. 日志收集监控告警平台的选型思考

    2024-03-24 09:46:02       38 阅读
  4. Github 2024-03-24 开源项目日报Top10

    2024-03-24 09:46:02       38 阅读
  5. 数据库第一次作业

    2024-03-24 09:46:02       36 阅读
  6. Ubuntu添加硬盘

    2024-03-24 09:46:02       40 阅读