贪心介绍 LeetCode 455.分发饼干 LeetCode 376. 摆动序列 LeetCode 53. 最大子序和

news2025/5/25 7:05:11

贪心介绍

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

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

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

但这种实现方式不一定总能达到全局最优。如有一堆盒子,你有一个背包体积为n,如何把背包尽可能装满,如果还每次选最大的盒子,就不行了。这时候就需要动态规划

注意点:

  • 贪心有什么固定的套路实现吗?说实话贪心算法并没有固定的套路。
  • 那么如何能看出局部最优是否能推出整体最优呢?有没有什么固定策略或者套路呢?不好意思,也没有! 靠自己手动模拟,如果模拟可行,就可以试一试贪心策略,如果不可行,可能需要动态规划。
  • 如何验证可不可以用贪心算法呢?最好用的策略就是举反例,如果想不到反例,那么就试一试贪心吧

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

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

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

LeetCode 455.分发饼干

思路

  • 将孩子的胃口和饼干的大小进行升序排序,通过两个指针来控制当前使用的饼干和当前吃饼干的孩子。
  • 如果当前饼干大于孩子胃口,则两个指针都右移。如果当前饼干小于孩子胃口,则饼干的指针右移,去获得更大的饼干。
  • 总的思路就是拿小饼干去喂给小胃口的学生,针对需要大胃口的学生才给大的饼干。

手撕Code

class Solution(object):
    def findContentChildren(self, g, s):
        """
        :type g: List[int]
        :type s: List[int]
        :rtype: int
        """

        ### g[]是孩子;  s[]是饼干
        
        ### 思路:对孩子的胃口和饼干的大小的升序排序,在两个数组中通过两个指针来判断当前饼干大小能否符合孩子的胃口。

        g_sorted = sorted(g)
        s_sorted = sorted(s)
        g_left = 0
        s_right = 0
        num = 0
        # print("g_sorted, s_sorted", g_sorted[g_left], s_sorted[s_right])

        while True: 
            if s_right == len(s_sorted) or g_left == len(g_sorted):
                break
            if s_sorted[s_right] >= g_sorted[g_left]:  ## 当前饼干的大小 比当前孩子的胃口大
                num += 1
                s_right += 1
                g_left += 1
            elif s_sorted[s_right] < g_sorted[g_left]:                 ## 饼干的大小 不足以满足当前孩子的胃口
                s_right += 1
        
        return num

Code

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  # 返回满足的孩子数目

又或者通过一个for循环来遍历饼干,如果饼干大小大于孩子的胃口时,再修改指向的孩子。

LeetCode 376. 摆动序列

需要考虑三种情况

  1. 上下坡有平坡
  2. 首尾元素
  3. 单调坡有平坡

需要明确判断当前节点是否满足摆动序列,如果当前节点的两边没梯度变化或者两边的梯度变化都是同向的,那就证明这个节点不符合摆动序列。这道题的贪心算法就是像不考虑这些,只考虑那些局部顶点或谷点。需要加以折现图辅助理解。

思路:

  • 通过一个prediff来记录当前节点与上一个节点的坡度,一个curdiff来记录下一个节点与当前节点的坡度。①如果prediff和curdiff为异号,那就证明当前的这三个节点符合摆动序列。②如果prediff和curdiff中其中一个为0,另外一个不为0,那就证明这三个节点中有两个节点符合摆动序列。③第②种方法存在缺陷,即整个序列是单调坡有坡的时候,此时,基于②去计算摆动序列长度的话会多算了。如何优化?当curdiff与prediff异号时,我们此时再更新prediff的位置。
  • 序列是从左到右进行遍历的,我们要从第二个元素开始进行遍历,先计算prediff和curdiff,当移动到下一个元素时,此时,先计算curdiff的值,如果curdiff与prediff异号,则将curdiff赋值作为prediff即可,之后再继续进行遍历。
  • 对于序列的第一个元素,其是没有prediff的,那么将其prediff看成是0,即其prediff是自己减掉自己。通过判断后续的curdiff来判断第一个元素是否符合摆动序列。
  • 根据以上curdiff和prediff所对应的出现摆动序列的情况进行计数。

左右梯度不同的情况

左右梯度存在一方为0的情况(非单调坡存在平坡)


左右梯度存在一方为0的情况(单调坡存在平坡)

手撕Code

class Solution(object):
    def wiggleMaxLength(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """

        if len(nums) == 1:
            return 1

        result = 0
        for i in range(0,len(nums)-1):
            if i == 0:
                prediff = nums[i] - nums[i]       ##只需计算一次,后续通过curdiff去更新prediff就行
            curdiff = nums[i+1] - nums[i]

            if (prediff >= 0 and curdiff < 0) or (prediff <= 0 and curdiff > 0):
                result += 1         ### 当前的这个节点是符合摆动序列中的局部最高/最低,而不是在单调坡的坡上
                prediff = curdiff

        return result+1

以序列nums = [1,7,4,9,2,5]举例,其流程如下:

LeetCode 53. 最大子序和

思路:

  • 采用连续和 + 下一个元素值的局部搜索方法去进行判断。当连续和为负数的时候,这时候就需要丢弃之前的计算了,因为你拿这个负数的连续和去进行相加只会是负担(让你去获得和最大的工程中)。因此当连续和为负数时,将count归零,从下一个元素开始进行计算。
  • 第一种方法适合于数组中存在正数和负数的情况,那对于全为负数的情况的话要另外解决。相对比较简单,对数组进行排序,如果数组的最大值为负数,那这个数组的最大值元素的值就当前这个全为负数的数组的最大子序和。

手撕Code

class Solution(object):
    def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """

        ### 不能对原数组进行排序来判断,这样的话你手动修改了数组的顺序。输出的数组在原数组不一定连续

        ### 思路 : 连续和 + nums[i], 当连续和是负数的时候,此时就抛弃掉前面的元素,从下一个元素开始进行计算
        ###                            另外,当连续和大于目前result的话,则将result进行更新,证明你补充下个元素进去有利于和变大

        result = 0
        count = 0
        path = []
        for i in range(len(nums)):      ### 针对数组中存在正数和负数的情况
            count += nums[i]
            if count > result:
                result = count
            if count < 0:
                count = 0

        nums_sorted = sorted(nums)             ### 如果整个数组都为负数, 那直接取负数中最大的一个值
        if nums_sorted[len(nums)-1] < 0:
            return nums_sorted[len(nums)-1]

        return result

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2385168.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Postgresql 数据库体系架构

1 postgresql 软件目录 rootu24-pg-110:~# tree -L 1 /usr/local/postgresql-17/ /usr/local/postgresql-17/ ├── bin #可执行二进制文件 ├── include ├── lib └── share 2 数据库目录及文件 #目录结构 base --每个数据库的子目录 global --数据库集簇范…

Vue框架1(vue搭建方式1,vue指令,vue实例生命周期)

一.VUE vue概述(vue.js) vue是前端JavaScript框架,对JavaScript进行封装,是一套用于构建用户界面的渐进式框架.vue的核心只关注图示层,不仅易上手,还便于与第三方库或既有的项目整合. vue.js和Angular.js,React.js一起,并称为前端三大主流框架 注意: 在此初步学习的是vue…

skywalking 10.2 源码编译

1.源码下载 Downloads | Apache SkyWalking 选择 SkyWalking APM 最新版下载&#xff0c; 下载后&#xff0c;在本地解压。 2.Idea加载工程 2.1 根目录pom文件删除checkstyle 插件 后续做二开时避免代码风格校验报错 2.2 删除apm-webapp 工程中 frontend-maven-plugin插件…

C++ --- string

C --- string 简介1、构造函数2、迭代器&#xff08;主流的遍历方式&#xff09;2.1字符串经典遍历和修改的方式2.2使用迭代器遍历和修改字符串2.3使用范围for遍历对象&#xff08;C11支持的新特性&#xff09; 3、常见&#xff0c;常用方法或重载3.1查询大小和容量管理3.2增3.…

Android Studio 连接夜神模拟器 自动断开的问题

版本情况&#xff1a; Android Studio Meerkat Feature Drop | 2024.3.2 Build #AI-243.25659.59.2432.13423653, built on April 30, 2025 Runtime version: 21.0.6-13368085-b895.109 amd64夜神模拟器 V7.0.5.9046 问题描述&#xff1a; cmd命令行使用adb连接夜神模拟器成…

Python入门手册:Python中的数据结构类型

在Python中&#xff0c;数据结构是组织和存储数据的方式&#xff0c;它们允许你以高效的方式操作和处理数据。Python提供了几种内置的数据结构&#xff0c;包括列表&#xff08;List&#xff09;、元组&#xff08;Tuple&#xff09;、集合&#xff08;Set&#xff09;和字典&a…

巡礼中国西极·跨越昆仑天山 | 北斗卫星徽章护航昆仑科考

神秘深邃&#xff0c;遗世独立。帕米尔高原&#xff0c;横亘于中亚东南部&#xff0c;我国的最西端&#xff0c;面积约10万平方千米&#xff0c;平均海拔4500米以上&#xff0c;古代丝绸之路在此经过。昆盖山&#xff0c;一座掩藏在帕米尔高原褶皱深处、鲜为人知的山脉&#xf…

Vue常用自定义指令-积累的魅力【VUE】

前言 在【自定义指令—v2与v3之间的区别【VUE基础】一文中&#xff0c;整理了自定义指令部分vue2和vue3 两个版本的区别&#xff0c;有兴趣的伙伴或者针对自定义部分比较迷茫的伙伴可以跳转看一下。此次主要介绍一些自己积累的一些自定义指令的代码&#xff0c;与大家一起分享。…

LangChain4j第三篇: RAG的简单应用与实践

引言:RAG 构建属于你的大模型 大语言模型(LLM)的知识体系本质上仅限于它所接受的训练数据。 其一在知识时效性方面,模型参数固化于训练完成的时点,而现实世界中的知识和信息持续动态更新。 其二在非公开数据层面,企业内部的机密文档(如产品设计图、商业策略等)及个人隐…

功能强大且易于使用的 JavaScript 音频库howler.js 和AI里如何同时文字跟音频构思想法

howler.js 是一个功能强大且易于使用的 JavaScript 音频库&#xff0c;它提供了跨浏览器的音频播放功能&#xff0c;支持多种音频格式&#xff0c;并且具有丰富的 API&#xff0c;可以方便地控制音频的播放、暂停、循环、音量等。下面是如何在 Vue 项目中使用 howler.js 实现音…

如何使用patch-package给npm包打补丁

一、背景 在移动应用开发中,轮播是一种很常见的效果,我们项目采用的是RN跨平台技术,RN的轮播我们直接使用的是第三方插件:react-native-snap-carousel。不过,当我们在项目中使用的时候却发现Android和iOS的表现不一致:https://stackoverflow.com/questions/60711611/rea…

maxkey单点登录系统

github地址 https://github.com/MaxKeyTop/MaxKey/blob/master/README_zh.md 1、官方镜像 https://hub.docker.com/u/maxkeytop 2、MaxKey:Docker快速部署 参考地址&#xff1a; Docker部署 | MaxKey单点登录认证系统 拉取docker脚本MaxKey: Dromara &#x1f5dd;️MaxK…

windows bat 在目录下(包括子目录)搜索批量指定文件名称复制到另一个文件夹内

windows bat 在目录下(包括子目录)搜索批量指定文件名称复制到另一个文件夹内 前言&#xff1a;最近遇到一个需求&#xff0c;我有15个文件夹(可能包含子文件夹) &#xff0c;目前我有一批文件名称&#xff0c;需要在这15个文件夹中查找出来&#xff0c;并拷贝到一个新的文件夹…

Notepad++ 下载与安装教程(小白专属)

文章目录 Notepad下载渠道的专业选择1. 官方网站下载&#xff08;海外用户或网络条件优越者首选&#xff09;2. 国内优化下载地址&#xff08;国内用户高效选择&#xff09; Notepad精细化安装流程解析总结与后续建议 在当前的开发与文本处理工作中&#xff0c;Notepad无疑是一…

Spring Cloud Gateway 微服务网关实战指南

上篇文章简单介绍了SpringCloud系列OpenFeign的基本用法以及Demo搭建&#xff08;Spring Cloud实战&#xff1a;OpenFeign远程调用与服务治理-CSDN博客&#xff09;&#xff0c;今天继续讲解下SpringCloud Gateway实战指南&#xff01;在分享之前继续回顾下本次SpringCloud的专…

微服务架构实战:Eureka服务注册发现与Ribbon负载均衡详解

微服务架构实战&#xff1a;Eureka服务注册发现与Ribbon负载均衡详解 一 . 服务调用出现的问题二 . EureKa 的作用三 . 服务注册3.1 搭建 EureKaServer① 创建项目 , 引入 spring-cloud-starter-netflix-eureka-server 的依赖② 编写启动类 , 添加 EnableEurekaServer 注解③ 添…

采用多维计算策略(分子动力学模拟+机器学习),显著提升 α-半乳糖苷酶热稳定性

字数 978&#xff0c;阅读大约需 5 分钟 在工业应用领域&#xff0c;α-半乳糖苷酶在食品加工、动物营养及医疗等方面发挥着重要作用。然而&#xff0c;微生物来源的该酶往往存在热稳定性不足的问题&#xff0c;限制了其在工业场景中的高效应用。近日&#xff0c;来自江南大学的…

【java】小练习--零钱通

文章目录 前言一、项目开发流程说明二、功能实现2.1 菜单2.2 零钱通明细2.3 零钱通收益2.4 零钱通消费2.5 零钱通退出确认2.6 零钱通金额校验2.7 完整代码 三、零钱通OOP版 前言 本文是我跟着B站韩顺平老师的 Java 教程学习时动手实现“零钱通”项目的学习笔记&#xff0c;主要…

Docker-mongodb

拉取 MongoDB 镜像: docker pull mongo 创建容器并设置用户&#xff1a; 要挂载本地数据目录&#xff0c;请替换此路径: /Users/Allen/Env/AllenDocker/mongodb/data/db docker run -d --name local-mongodb \-e MONGO_INITDB_ROOT_USERNAMEadmin \-e MONGO_INITDB_ROOT_PA…

Gartner《Optimize GenAI Strategy for 4 Key ConsumerMindsets》学习心得

一、引言 在当今数字化营销浪潮中,生成式人工智能(GenAI)正以前所未有的速度重塑着市场格局。GenAI 既是一场充满机遇的变革,也是一场潜在风险的挑战。一方面,绝大多数 B2C 营销领导者对 GenAI 赋能营销抱有极高期待,他们看到了 GenAI 在提升时间与成本效率方面的巨大潜…