代码随想录算法训练营Day31|贪心算法理论基础、455.分发饼干、376. 摆动序列、53. 最大子序和

目录

贪心算法理论基础

什么是贪心?

什么时候用贪心?

455.分发饼干

前言

思路

算法实现

 376. 摆动序列

前言

 算法实现

53. 最大子序和

方法一:暴力解法

方法二:贪心算法

总结


贪心算法理论基础

文章链接icon-default.png?t=N7T8https://programmercarl.com/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

什么是贪心?

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

什么时候用贪心?

        如果该问题能够通过拆分成局部最优从而得到全局最优并且举不出明显的反例,那么就可以用贪心算法。对于贪心算法的具体实现,不同题目有不同的具体实现,没有统一的模板,所以得结合具体的题目学习。

455.分发饼干

题目链接

文章链接

前言

         本题要使不同大小的饼干和胃口之间得到合理的分配,为了满足更多的小孩,就不要造成饼干尺寸的浪费。大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子,那么就应该优先满足胃口大的(或者小尺寸的饼干优先分给胃口小的)。

思路

        参照上面大饼干喂给大胃口的思路,这里的局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。可以尝试使用贪心策略,先将饼干数组和小孩数组排序。然后从后向前遍历小孩数组,用大饼干优先满足胃口大的,并统计满足小孩数量。

算法实现

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

        也可以使用第二种思路(小尺寸的饼干先分给胃口小的),这种方式要依次遍历饼干数组,统计满足条件的饼干个数,直接返回满足条件的饼干数即可。

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;}
};

 376. 摆动序列

题目链接

文章链接

前言

         本题要求通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。如果能够画出序列上下摆动的坡度图就能很好理解。

        局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列

        在实际操作上并不需要删除的操作,因为只要求最长摆动序列的长度,所以只需要统计数组的峰值数量就可以。因此目的是让峰值尽可能的保持峰值,然后删除单一坡度上的节点。

        在计算是否有峰值的时候,通过计算当前值和前一个节点值的差值prediff(nums[i] - nums[i - 1]) 和当前值与下一个节点值的差值curdiff(nums[i + 1] - nums[i]),如果prediff(nums[i] - nums[i - 1])  < 0 && curdiff(nums[i + 1] - nums[i]) > 0 或者 prediff(nums[i] - nums[i - 1])  > 0 && curdiff(nums[i + 1] - nums[i]) < 0,此时就有波动(峰值)需要统计。

        以上分析是大体思路,但是还要考虑三种情况:

  1. 情况一:上下坡中有平坡;
  2. 情况二:数组的首尾两端;
  3. 情况三:单调坡中有平坡;

        为了解决第一种情况,在平坡中我们只针对一个元素做处理,不考虑其余相同元素,统一规则只看平坡最右侧的元素,此时对峰值波动的统计规则则改为 prediff <= 0 && curdiff > 0 或者 prediff  >= 0 && curdiff < 0。

        对于第二种情况,我们以上的分析都是针对数组有三个数字以上的,对于一个元素的数组我们可以直接返回它的大小(符合题目条件),对于两个元素的数组,,结构为2,可以直接写死,当两个元素不相同时直接返回2,也可以按照上述条件来,对于第一个元素,当做它前面有一个平坡,相当于preDiff = 0,对于末尾元素,可以默认序列最右边有一个峰值,即result从一开始计数。

        对于第三种情况,只要更改preDiff和curDiff的赋值位置就可以,不要在每次循环中事实更新preDiff的位置,只有在到达一个新的峰值的时候再更新preDiff的位置。

 算法实现

class Solution {
public:int wiggleMaxLength(vector<int>& nums) {if (nums.size() <= 1) return nums.size();int curDiff = 0; // 当前一对差值 int preDiff = 0; // 前一对差值int result = 1; // 记录峰值个数,默认序列最右边有一个峰值for (int i = 0; i < nums.size() - 1; i++){curDiff = nums[i + 1] - nums[i];// 出现峰值if ((preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)){result++;preDiff = curDiff;}}return result;}
};

53. 最大子序和

题目链接

文章链接

方法一:暴力解法

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

        本题的暴力解法还是很好想的,两层for循环,第一层依次向前遍历数组元素,第二层加上符合条件的数组元素,在遍历每一次元素时要重新将总和sum置零,从新向后累加数组的值,然后判断新的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;}
};

        本题的贪心实现较为巧妙,如果当前累加的sum值已经小于0,那么加上后面的值只会使后面的值更小,因此直接重新归0,从下一个值重新求和,然后在判断每次记录的result值和新的sum值哪个更大,记录较大值。

总结

        经过了回溯算法的摧残之后,刚接触贪心算法容易了很多,虽然没有固定的套路模板,但是在实现思想上还是比较好接受的。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB | 龙年大吉,使用MATLAB绘制会动的中国风神龙

hey各位好久不见&#xff0c;龙年到了&#xff0c;这期画一期配色非常中国风的龙&#xff0c;这个造型的龙参考了某些html绘制龙的视频&#xff0c;但是由于html版全网都是也不咋给代码和代码出处&#xff0c;因此自己写了个MATLAB版本&#xff1a; 可以看到还是非常酷炫的&…

图灵日记之java奇妙历险记--String类

目录 String常用方法字符串构造String对象的比较字符串查找char charAt(int index)int indexOf(int ch)int indexOf(int ch, int fromIndex)int indexOf(String str)int indexOf(String str, int fromIndex)int lastIndexOf(String str)int lastIndexOf(String str, int fromIn…

WAF攻防相关知识点总结1--信息收集中的WAF触发及解决方案

什么是WAF WAF可以通过对Web应用程序的流量进行过滤和监控&#xff0c;识别并阻止潜在的安全威胁。WAF可以检测Web应用程序中的各种攻击&#xff0c;例如SQL注入、跨站点脚本攻击&#xff08;XSS&#xff09;、跨站请求伪造&#xff08;CSRF&#xff09;等&#xff0c;并采取相…

C语言——大头记单词

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 每一发奋努力的背后&#xff0c;必有加…

前端面试题(持续更新~~)

文章目录 一、基础1、数组常用的方法2、数组有哪几种循环方式&#xff1f;分别有什么作用&#xff1f;3、字符串常用的方法4、原型链5、闭包6、常见的继承7、cookie 、localstorage 、 sessionstrorage区别8、数组去重方法9、http 的请求方式10、数据类型的判断方法11、cookie …

植物大战僵尸-C语言搭建童年游戏(easyx)

游戏索引 游戏名称&#xff1a;植物大战僵尸 游戏介绍&#xff1a; 本游戏是在B站博主<程序员Rock>的视频指导下完成 想学的更详细的小伙伴可以移步到<程序员Rock>视频 语言项目&#xff1a;完整版植物大战僵尸&#xff01;可能是B站最好的植物大战僵尸教程了&…

Red Hat Enterprise Linux 7.9 安装图解

引导和开始安装 选择倒计时结束前&#xff0c;通过键盘上下键选择下图框选项&#xff0c;启动图形化安装过程。需要注意的不同主板默认或者自行配置的固件类型不一致&#xff0c;引导界面有所不同。也就是说使用UEFI和BIOS的安装引导界面是不同的&#xff0c;如图所示。若手动调…

第16章_网络编程拓展练习(TCP编程,UDP编程)

文章目录 第16章_网络编程拓展练习TCP编程1、学生与老师交互2、查询单词3、拓展&#xff1a;查询单词4、图片上传5、拓展&#xff1a;图片上传6、多个客户端上传文件7、群聊 UDP编程8、群发消息 第16章_网络编程拓展练习 TCP编程 1、学生与老师交互 案例&#xff1a;客户端模…

【02】mapbox js api加载arcgis切片服务

需求&#xff1a; 第三方的mapbox js api加载arcgis切片服务&#xff0c;同时叠加在mapbox自带底图上 效果图&#xff1a; 形如这种地址去加载&#xff1a; http://zjq2022.gis.com:8080/demo/loadmapbox.html arcgis切片服务参考链接思路&#xff1a;【01】mapbox js api加…

java.lang.UnsupportedOperationException: null 其一解决办法

文章目录 前言一、错误回顾1.详细信息2.代码详情 二、解决方案1.错误原因2.解决方案1.使用 new ObjectMapper() new TypeReference<List>(){}2.使用 SerializerFeature.WriteMapNullValue.getMask() 总结 前言 当我们远程调用传递泛型集合&#xff0c;如 List<?>…

Angular系列教程之观察者模式和RxJS

文章目录 引言RxJS简介RxJS中的设计模式观察者模式迭代器模式 示例代码RxJS 在 Angular 中的应用总结 引言 在Angular开发中&#xff0c;我们经常需要处理异步操作&#xff0c;例如从后端获取数据或与用户的交互。为了更好地管理这些异步操作&#xff0c;Angular中引入了RxJS&…

JOSEF约瑟 过电流继电器JL12-40A 线圈额定电流40A 柜内安装

系列型号 JL12-15A电流继电器JL12-20A电流继电器 JL12-30A电流继电器JL12-40A电流继电器 JL12-60A电流继电器JL12-75A电流继电器 JL12-100A电流继电器JL12-150A电流继电器 JL12-200A电流继电器JL12-300A电流继电器 一、概述 过流继电器JL12-40A适用于电压为380V&#xff…

C++系列-第1章顺序结构-9-字符类型char

在线练习&#xff1a; http://noi.openjudge.cn/ https://www.luogu.com.cn/ 总结 本文是C系列博客&#xff0c;主要讲述字符类型char 字符类型char 在C编程语言中&#xff0c;char是一种基本的数据类型&#xff0c;它用于存储单个字符。字符可以是字母、数字、标点符号或者…

计算机网络-ACL访问控制列表

上一篇介绍NAT时候就看到了ACL这个东西了&#xff0c;这个是什么意思&#xff1f;有什么作用呢&#xff1f; 一、ACL访问控制列表 访问控制列表 (ACL, Access Control List)是由一系列permit或deny语句组成的、有序规则的列表。ACL是一个匹配工具&#xff0c;能够对报文进行匹配…

C语言--质数算法和最大公约数算法

文章目录 1.在C语言中&#xff0c;判断质数的常见算法有以下几种&#xff1a;1.1.试除法&#xff08;暴力算法&#xff09;&#xff1a;1.2.优化试除法&#xff1a;1.3.埃拉托色尼筛法&#xff1a;1.4.米勒-拉宾素性检验&#xff1a;1.5.线性筛法&#xff1a;1.6.费马小定理&am…

Android Activity的启动流程(Android-10)

前言 在Android开发中&#xff0c;我们经常会用到startActivity(Intent)方法&#xff0c;但是你知道startActivity(Intent)后Activity的启动流程吗&#xff1f;今天就专门讲一下最基础的startActivity(Intent)看一下Activity的启动流程&#xff0c;同时由于Launcher的启动后续…

Spring Boot整合JUnit

引言 测试是软件开发过程中不可或缺的一环&#xff0c;而JUnit作为Java生态中最流行的测试框架之一&#xff0c;与Spring Boot的整合为开发者提供了一套强大的测试工具。本文将讨论Spring Boot整合JUnit的技术细节、最佳实践以及测试驱动开发&#xff08;TDD&#xff09;的优雅…

Android: alarm定时很短时,比如500ms,测试执行mPowerManager.forceSuspend()后,系统不会suspend

参考文档&#xff1a; https://blog.csdn.net/weixin_35691921/article/details/124961404 Android: alarm定时很短时&#xff0c;比如500ms&#xff0c;然后执行mPowerManager.forceSuspend()后&#xff0c;系统不会suspend&#xff0c;原因分析&#xff1a; static int ala…

数学建模--比赛

内容来自数学建模BOOM&#xff1a;【快速入门】北海&#xff1a;数模建模基础MATLAB入门论文写作数学模型与算法(推荐数模美赛国赛小白零基础必看教程)_哔哩哔哩_bilibili 目录 1.学习内容 2.参赛须知 1&#xff09;参赛作品的组成 2)参赛作品的提交 3.软件安装 4.注意…

Python实战 -- PySide6 制作天气查询软件

一、环境准备 开发环境&#xff1a;Python 3.9.2 pycharm PySide6 申请天气情况 API &#xff1a;https://console.amap.com/dev/key/app designer 设计 ui 目录下 Weather.ui 转换为 Weather.py 结果显示 二、完整代码 import sysfrom PySide6 import QtWidgetsimport…