【算法练习Day26】分发饼干摆动序列 最大子数组和

news2024/10/3 22:16:36

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:练题
🎯长路漫漫浩浩,万事皆有期待

文章目录

  • 分发饼干
  • 摆动序列
  • 最大子数组和
  • 总结:

本期开始新的篇章,贪心算法题目的讲解。

贪心算法,没有固定的套路,通常根据做题人的做题经验,才能写出贪心算法。且算法有难度,并不总是简单的。贪心算法是一种常识思想,需要在做题中慢慢感觉和领悟。

分发饼干

455. 分发饼干 - 力扣(LeetCode)

分发饼干,是一道贪心算法的启蒙题(但是实际上我三道题都未能自己做出来,对贪心算法一无所知)。
在这里插入图片描述

题目大意是将一些饼干分发给一些小孩子们,小孩子们胃口各不相同,且每个孩子只能喂食一块饼干,要求是饼干的尺寸大于等于孩子的胃口值,求最多可以使几个孩子吃饱?解题的思路是我们可以创建一个变量count来记述我们已经满足了几个孩子,然后将孩子数组和饼干数组分别排序,使它们变得有序方便操作,用一个循环控制两个变量,当满足时候让饼干下标和孩子下标分别往后走,count自增,不满足只让饼干下标向后走,这样的原因是两数组有序,那么满足这个孩子的饼干如果存在,那么只可能在后面的饼干,而如果连这个孩子都无法满足,那肯定后面的孩子也无法满足。这就是排序的好处,如果不排序,那一个孩子需要遍历全部饼干,同样也要遍历所有孩子,这样会严重影响代码效率,时间为O(N^2)。

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) 
    {
        sort(g.begin(),g.end());sort(s.begin(),s.end());
        int count=0;
        for(int i=0,j=0;i<g.size()&&j<s.size();)
        {
            if(s[j]>=g[i])
            {
                count++;
                i++;
                j++;
                continue;
            }
            j++;
        }
        return count;
    }
};

排序起初我没有想到,但是看了题解我想到了这种方法,代码看起来略显冗余,下面看一个思路一样但是代码却很精简也不用count来计数的方法。

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) 
    {
        sort(g.begin(),g.end());sort(s.begin(),s.end());
        int index=0;
        for(int i=0;i<s.size();i++)
        {
            if(index<g.size()&&g[index]<=s[i])
            {
                index++;
            }
        }
        return index;
    }
};

我们用index来代替count和小孩数组的下标,用i来代替饼干下标,核心的思路是相同的,保证不要越界,然后当饼干能够满足小孩,index就自增,怎么样是不是简洁了不少,而且还巧妙的用孩子下标做了返回值。

摆动序列

376. 摆动序列 - 力扣(LeetCode)
在这里插入图片描述

在做这道题时候特别懵,没有任何思路,看了题解也很懵,后来想了一阵才慢慢明白。

题的大意是求摆动序列,可以删除改定序列的若干个元素,最后构成一个摆动序列,摆动序列的定义是严格按照数字之间的差值,在正数和负数之间来回摆动。实现预判式的在一个序列里删除某些节点而达到拼成最大摆动序列是十分困难的。

我们给出另一种解题思路,让我们不用删除节点,却起到了删除节点的效果。具体做法为,将一个序列模拟成山峰和山谷的示意图,也就是说把这些数都画出来,看它们的拐向,我们只要拐向一次向上一次向下的那种,如果中间是连续向上或者向下亦或者是平的(两个相邻数相等)我们全都统统不要。那么如何知道中间要删除这些节点,然后还能将删除后的两段连上呢?这是十分巧妙的做法,我们先定义两个变量一个代表上一次两个数的差值,另一个代表的是现在的相邻两个数的差值,如果两个差值是有正负变化的(前一个差值是0现在的差值是大于0或者小于0的同样符合摆动,反过来也是),那么就将计数器加1,且上一个的差值被改成当前的,然后进行下一次的循环。

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if(nums.size()<=1)return nums.size();
        int cur=0;int pre=0;int count=1;
        for(int i=0;i<nums.size()-1;i++){
            cur=nums[i+1]-nums[i];
            if((cur>0&&pre<=0)||(cur<0&&pre>=0)){
                count++;
                pre=cur;
            }
            
        }
        return count;
    }
};

还有一些细节,需要交代一下,首先我们知道如果有摆动序列,那么至少要有1个数据来组成该序列,所以我们count要从1开始起,这是很关键的,由于我们让count从1开始,那么有几个拐点直接加在一起,就是此时最大摆动序列的总长度,而为什么要将pre=cur写到if的里面呢?如果if没进去我们就不改写前一个差的数值?实际上我们可以通过模拟得知,这种写法和把它写到外面在一般的测试用例下,跑出来的答案是一样的

但是如果碰到了序列走势是向上–平–向上这种情况呢?这种情况把pre写在if的外面会使拐点多算一次,实际上我们摆动序列是2,这样算起来是3,所以不能这样写,摆动序列的定义不能连续向上,即使中间有平也不行,况且平本来就不算在内,这也是代码的关键所在,它模拟出了,我们在真实删除数据时,是如何将删除后两段又重新链接在一起了,由于判断摆动符合我们才改变pre的值,所以不符合时候它一直是上一次符合时候的差值,当再次符合时进入if我们才改动pre,这也就相当于联系起了删除中间节点后两个链条的连接,这里的代码虽然简短,但是每一步的思路,尤其重要,建议大家用心去体会其过程的巧妙之处。

最大子数组和

53. 最大子数组和 - 力扣(LeetCode)

求最大的子数组连续和,这道题的题目大意和题目名字相同,首先能想到的一种思路是暴力法,双for来解决问题,一个for循环控制数组起始位置遍历,一个控制终点,两层遍历后,找到最大子数组和是多少返回,这种方法貌似以前是可以通过的,但是现在不行了,直接提交这种暴力解法会提示超时,这道题同样我们也是可以用贪心来做出来的。

思路其实很简单,我们用sum来记录当前总和,再用一个变量result来记录我们历史记录中取到的最大值,和它作比较,比result大则与之交换,而贪的是如果sum小于0,直接sum=0再从当前位置向后与sum相加,再记录,而暴力解法中的数组结束位置,我们用每次的result判断来代替,每一次循环都判断一次也就相当于这一步骤了

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int result=INT_MIN;int sum=0;
        for(int i=0;i<nums.size();i++){
            sum+=nums[i];
            if(sum>result)
            result=sum;
            if(sum<0)sum=0;
        }
        return result;
    }
};

如果数据全是-1呢?那它会求得答案为0吗?肯定是不会的,自行调试便知道,在sum=0之前由于我们result取得是int里最小的数,我们先行进行交换使result=-1,然后sum=0后再加上-1,结果还是-1它不可能变成0,这也就是为什么要把sum+=数据写在前面,result=最小数,是为了避免有负数和的产生。

从以上三题中,我个人认为,求某个条件下的最大的某某数这类题,应该是可以考虑用贪心算法做一下的,除了第二题有些难想外,第一题和第三题实际上确实是“常识”类的解题思路,但是有时候确实没有做过的话,还是无法做得出来,重要的是多多积累和总结,第一题实际上我觉得最重要的是排序,没有排序我们不可能那么轻易的解出来,而不用遍历那么多的数据,第二题是运用峰值的巧妙之处,求取了最长的摆动序列数据个数,第三道题贪的是sum小于0立刻重新计数

为什么当它为负数时候,直接sum=0了却不从之前数组统计的下一个开始计数,而是直接从当前位置向后计数呢?因为之前的数相加时候我们已经用resul来记录了这一段数据中最大的数是多少,数据是要连续的遍历相加。还不懂,不妨举一个例子,例如数据整体序列为{-5,3,4,-8,5}我们知道最大子数组和肯定是5,那我们看前面,走到-5直接跳了出来,然后3+4-8才跳了出来,那你说4-8会比3+4-8还要大吗?

肯定不能,这是一种情况说明了如果前一个数和后一个数都是正数那么实际上从它的下一个位置开始走,不可能找得到比从刚才那个数还大的组合了,那有人会说如果前一个数是负数后一个数是正数不就能找的到了吗也同样的可以模拟如果还是{-5,3,4,-8,5}那样的话第一个-5遇到了后面直接sum=0了,如果是{-5,3,-2,7,5}那从3向后遍历的和实际上是比从正数7大的,很多时候我们都可以用模拟来解决问题。

总结:

今天我们完成了分发饼干、摆动序列、最大子数组和三道题,相关的思想需要多复习回顾。接下来,我们继续进行算法练习。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

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

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

相关文章

金蝶云星空企业版v8.0内网穿透配置详解:实现便捷的异地远程访问

文章目录 前言1. 金蝶云星空企业版v8.0安装下载1.1 登录金蝶官网下载安装包1.2 常见的安装下载问题 2. 金蝶云星空配置SQL Sever数据库2.1 创建数据管理中心2.2 创建完成后在服务器登录管理站点 3. 下载安装注册cpolar3.1 公网访问测试 4. 固定连接公网地址 前言 金蝶云星空专注…

关于AES加密输出密文不为128位的倍数的原因

今天尝试用AES-256-OFB加密一个flag结果输出的密文是43字节&#xff0c;不是128位&#xff08;16字节&#xff09;的倍数&#xff0c;代码如下&#xff1a; import os from Crypto.Cipher import AES databflag{a7ba7128-3917-4551-8260-b3499e9dd7b12} aes AES.new(os.urand…

如何用Pytest做性能测试?5个步骤轻松学会!

Pytest其实也是可以做性能测试或者基准测试的。是非常方便的。 可以考虑使用Pytest-benchmark类库进行。 安装pytest-benchmark 首先&#xff0c;确保已经安装了pytest和pytest-benchmark插件。可以使用以下命令安装插件&#xff1a; pip install pytest pytest-benchmark …

Apollo生态系统探索:更多工具与框架的介绍

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

选择合适的软件管理视频制作排期

如果你是一名专业的视频创作者&#xff0c;那么你一定知道一个清晰、高效的项目管理对于视频制作的重要性。那么如何使用Zoho Projects项目管理软件来管理的视频制作项目&#xff0c;以便更好地规划和执行每一个细节呢&#xff1f; 这款项目管理软件具有丰富的自定义字段功能&a…

【Java集合类面试十三】、HashMap如何实现线程安全?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;HashMap如何实现线程安全…

【EtherCAT】二、下载并使用TwinCAT

下载并使用TwinCAT 引言介绍下载安装TwinCAT使用 更多精彩&#xff0c;欢迎关注 引言 TwinCAT是一款由德国Beckhoff Automation开发的工业自动化控制软件。它被广泛用于工厂自动化、过程控制、机器控制以及其他自动化领域。 而这里我们主要使用TwinCAT模拟ECAT主站。本文将介绍…

【蓝桥杯001】

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大二在校生&#xff0c;喜欢编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;小新爱学习. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc…

golang 工程组件:grpc-gateway 环境安装+默认网关测试

grpc-gateway grpc-gateway 顾名思义是专门是grpc的网关。也是一个protobuf的编译器&#xff0c;是一个proto的插件。 grpc-gateway就是将http请求处理后转发到对应grpc服务上。很多浏览器&#xff0c;或者客户端开箱不支持grpc&#xff0c;只支持传统的restful API。 grpc网关…

Tmux:终端复用器的基本使用(三)

相关阅读 Tmuxhttps://blog.csdn.net/weixin_45791458/category_12472796.html?spm1001.2014.3001.5482 在之前的两篇文章中&#xff0c;已经给出了关于tmux中会话和窗口相关的常用命令&#xff0c;在这篇文章中&#xff0c;窗格相关的命令将会被给出。 将一个窗格水平和垂直…

MECE分析法

1、前言 前段时间在对项目进行问题分析的时候&#xff0c;领导要求要符合MECE原则&#xff0c;做到逻辑完整而不能遗漏。虽然没听过这个原则&#xff0c;但是总感觉很有道理&#xff08;领导说的都对&#xff09;。于是乎&#xff0c;就找了一些资料了解了一下。 MECE分析法是…

Mysql 索引原理和优化方式

一、索引原理 什么是索引 索引是存储引擎用于快速找到记录的一种数据结构。可以联想到字典中的目录。 索引的分类 &#xff08;1&#xff09; Hash 索引 Hash 索引是比较常见的一种索引&#xff0c;他的单条记录查询的效率很高&#xff0c;时间复杂度为1。但是&#xff0c…

《红蓝攻防对抗实战》四.内网探测协议出网之ICMP协议探测出网

目录 一.Windows系统探测ICMP协议出网 1. Ping命令 2.Tracert 命令 二.Linux系统探测ICMP协议出网 1. Ping命令 ICMP&#xff08;Internet Control Message Protocol&#xff09;是一种面向无连接的协议&#xff0c;属于网络层的协议&#xff0c;用于检测网络通信故障和实…

MySQL中的表操作,配置文件,储存引擎,数据类型

MySQL中的表操作 1 查库&#xff08;已密码登陆mysql&#xff09; show databases; 2 添加库 create database t1; 3 表操作 1选定操作库 use t1 2在库里添加表格式 create table t1(id int, name varchar(32), gender varchar(32),age int); 3往表里添加具体元素 insert…

HDMI ——CEC 协议详解以及待机唤醒 实现

本文讲解的是基于HDMI CEC的待机唤醒方案的设计。 目录 cec基本介绍 CEC协议时序&#xff1a; CEC数据帧 cec待机唤醒介绍 待机唤醒的处理流程和实现 cec基本介绍 如今常见的高清视频接口有HDMI,VGA,DP和DVI。HDMI&#xff08;High-Definition Multimedia Interface&…

嵌入式linux系统设备树实例分析

前言 我们可以从LED程序中榨取很多知识&#xff1a;基本的驱动框架、驱动的简单分层、驱动的分层分离思想、总线设备驱动模型、设备树等。这大多都是结合韦老师的教程学的。 这篇笔记结合第6个demo&#xff08;基于设备树&#xff09;来学习、分析&#xff1a; 框图 下面是L…

10 创建型模式-原型模式

引言&#xff1a; 创建对象的五种方式&#xff1a; 通过new关键字通过Class类的newInstance()方法通过Constructor类的newInstance()方法利用Clone方法反序列化 Clone方法&#xff1a; 其实现方式正是通过调用 Object 类的 clone() 方法来完成。 protected native Object cl…

python安装.whl文件

python --version https://www.lfd.uci.edu/~gohlke/pythonlibs/ 用CtrlF找需要安装的包 下载对应版本的whl python3.8 把下载好的whl放到安装路径下&#xff1a;C:\Users\Administrator\AppData\Local\Programs\Python\Python38\Lib\site-packages 并在该路径下打开cmd执行…

GaussDB数据库管理系统介绍

1.GaussDB的发展 2.GaussDB的生态 内部&#xff1a; 云化自动化方案。通过数据库运行基础设施的云化将DBA(数据库管理员)和运维人员的日常工作 自动化。外部&#xff1a; 采用与数据库周边生态伙伴对接与认证的生态连接融合方案&#xff0c;解决开发者/DBA难获取、应用难对接等…

Linux绝对路径和相对路径

在 Linux 中&#xff0c;简单的理解一个文件的路径&#xff0c;指的就是该文件存放的位置。 只要我们告诉 Linux 系统某个文件存放的准确位置&#xff0c;那么它就可以找到这个文件。指明一个文件存放的位置&#xff0c;有 2 种方法&#xff0c;分别是使用绝对路径和相对路径。…