Day31|贪心算法1

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

无固定套路,举不出反例,就可以试试贪心。

一般解题步骤:

1.将问题分解成若干子问题

2.找出适合的贪心策略

3.求解每一个子问题的最优解

4.将局部最优解堆叠成全局最优解

分发饼干

思路:为了满足更多的小孩,就不要造成饼干尺寸的浪费,大尺寸的饼干既可以满足胃口大的孩子,也可以满足胃口小的孩子,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。可以尝试使用贪心策略,先将饼干数组和小孩数组进行排序。然后从后向前遍历小孩数组,用大饼干优先满足胃口大的,并统计满足小孩数量。

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

从代码中可以看出,index用来控制饼干数组的遍历,遍历饼干没有再起一个循环,而是采用自减的方式,这是常用的技巧。

不可以先遍历比骨干再遍历胃口,因为外面for,i是固定移动的,if的index才是符合条件移动的。

 反过来,先满足胃口小的,从小到大去满足:

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 < size(); i++){if(index < g.size() && g[index] <= s[i]){index++;}}return index;}
};
//思路一
class Solution{public int findContentChildren(int[] g, int[] s){Arrays.sort(g);Arrays.sort(s);int start = 0;int count = 0;for(int i = 0; i < s.length && start < g.length; i++){if(s[i] >= g[start]){start++;count++;}}return count;}
}
class Solution{public int findContentChildren(int[] g,int[] s){Arrays.sort(g);//排序胃口Arrays.sort(s);//排序饼干int count = 0;int start = s.length - 1;//胃口数组长度,从start开始遍历,倒着遍历,先考虑胃口大的//遍历胃口,从大到小for(int index = g.length - 1;index >= 0;index--){if(start >= 0 && g[index] <= s[start]){start--;//从大到小count++;//满足一个计数+1}}return count;//返回计数}
}

摆动序列

如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在地话),可能是正数或负数,少于两个元素的序列也是摆动序列。

给定一个整数序列,返回作为摆动序列的最长子序列的长度。通过从原始序列中删除一些元素来获得子序列,剩下的元素保持其原始顺序。

思路:

贪心

删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值。

整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列。

实际操作中,删除操作都不用,因为题目要求的是最长摆动子序列的长度,所以只需要统计数组的峰值数量就可以了(相当于是删除单一坡度上的节点,然后统计长度)

这就是贪心所贪的地方, 让峰值尽可能地保持峰值,然后删除单一坡度上的节点。

在计算是否有峰值的时候,大家知道遍历的下标i,计算presiff(nums[i] - nums[i - 1])和curdiff(nums[i + 1] - nums[i]),如果presiff < 0 && surdiff > 0或者prediff > 0 && curdiff < 0,此时就有波动就需要统计。

这是我们思考本题的一个大体思路,但本题还要考虑三种情况:

1.上下坡有平坡

[1,2,2,2,2,1]删除左边的三个2,或者删除右边的三个2,摆动长度为3

当i指向第一个2的时候,prediff > 0&&curdiff=0,当 i 指向最后一个2的时候,prediff=0 && curdiff <0.

如果采用删除左面三个2的规则,那么当prediff = 0&&curdiff < 0也要记录一个峰值,因为他是把之前相同的元素都删掉留下的峰值。

我们记录峰值的条件应该是:(preDiff <=0 &&curDiff > 0)||(preDiff >= 0&&curDiff < 0) 

2.数组首尾两端

本题统计峰值的时候,数组最左面和最右面如何统计。

当有两个不同的元素时,摆动序列也是2.

例如[2,5],如果靠统计差值来计算峰值个数,就需要考虑数组最左面和最右面的特殊情况。

因为我们在计算prediff(nums[i] - nums[i - 1])和curdiff(nums[i+1] - nums[i])的时候,至少需要三个数字才能计算,而数组只有两个数字。这里如果只有两个数字,且是不同的元素,那结果为2.

3.单调坡中有平坡

之前我们在讨论 情况一 :相同数字练习的时候,prediff = 0,curdiff < 0或者>0也记为波谷

为了统一规则。针对序列[2,5],可以假设为[2,2,5],这样就有了坡度,即preDiff = 0.

[2,2,5]

针对以上情形,result初始值为1,此时curDiff > 0&&preDiff<=0,那么result++(计算了左面的峰值),最后得到结果为2(峰值个数为2即摆动序列长度为2)

class Solution{
public:int wiggleMaxLength(vector<int>&nums){if(num.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;}};
}

3.在上面解法中,忽略了第三种情况,即如果在一个单调坡度上有平坡,例如[1,2,2,2,3,4]

图中我们可以看出,应该记录2,单调中的平坡不能算作峰值(摆动)

 需要在坡度摆动变化时,更新prediff,这样prediff在单调区间有平坡的时候就不会发生变化,造成误判。

class Solution{
public:int wiggleMaxLength(vctor<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;}
};

用动态规划求解

思路:

对于我们当前考虑的这个数,要么是作为山峰(nums[i] > nums[i - 1]),要么是作为山谷(即nums[i] < nums[i-1])

设dp状态dp[i][0],表示考虑前i个数,第i个数作为山峰的摆动子序列的最长长度。

设dp状态为dp[i][1],表示考虑前i个数,第i个数作为山谷的摆动子序列的最长长度

则转移方程为:

dp[i][0] = max(dp[i][0],dp[j][1]  + 1),其中0<j<i且nums[j] < nums[i],表示将

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

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

相关文章

【MySQL】深入解析 Buffer Pool 缓冲池

文章目录 1、前置知识1.1、Buffer Pool介绍1.2、后台线程1.2.1、Master Thread1.2.2、IO Thread1.2.3、Purge Thread1.2.4、Page Cleaner Thread 1.3、重做日志缓冲池 2、Buffer Pool 组成2.1、数据页2.2、索引页2.3、undo页2.4、插入缓冲2.5、锁空间2.6、数据字典2.6、自适应哈…

JavaScript之structuredClone现代深拷贝

在JavaScript中&#xff0c;实现深拷贝的方式有很多种&#xff0c;每种方式都有其优点和缺点。今天介绍一种原生JavaScript提供的structuredClone实现深拷贝。 下面列举一些常见的方式&#xff0c;以及它们的代码示例和优缺点&#xff1a; 1. 使用JSON.parse(JSON.stringify(…

代码随想录 二叉树第四周

目录 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树 530.二叉搜索树的最小绝对差 501.二叉搜索树中的众树 236.二叉树的最近公共祖先 617.合并二叉树 617. 合并二叉树 简单 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其…

【Rust】——切片

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

第105讲:Mycat垂直分表实战:从规划到解决问题的完整指南

文章目录 1.垂直分表的背景2.垂直分表案例实战2.1.垂直分表规划2.2.配置Mycat实现垂直分表2.3.重启Mycat2.4.在Mycat命令行中导入数据结构2.5.查看由Mycat分表后每个分片上存储的表2.6.Mycat垂直分表后可能遇到的问题2.7.垂直分表完成 1.垂直分表的背景 我们的商城系统数据库&…

Unity编辑器下如何获取物体(GameObject)的中心位置

注意仅能在编辑器下才能使用该方法 实现方式依靠UnityEditor.Tools提供的参数&#xff0c;具体实现如下&#xff1a; 获取单个物体的中心坐标 public static Vector3 GetGameObjectCenter(GameObject gameObject) {// 选中物体Selection.activeObject gameObject;// 记录当前…

C#中Byte.Parse的用法,如果需要解析含有数字以外的字符,应该如何使用?

在C#中&#xff0c;Byte.Parse用于将字符串解析为byte类型的数字。它的用法如下&#xff1a; byte result Byte.Parse(str);其中&#xff0c;str是要解析的字符串。 如果要解析的字符串含有数字以外的字符&#xff0c;Byte.Parse会抛出一个FormatException异常。为了处理这种…

javaWebssh水利综合信息管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh水利综合信息管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCA…

MATLAB 实现贝叶斯决策

1. 原理 后验概率&#xff1a; 1.最小错误率决策&#xff08;最大后验概率决策&#xff09;&#xff1a; 2.最小风险决策&#xff1a; 3.正态分布下的贝叶斯决策 2. 过程 2.1 训练集数据可视化 导入两类训练集数据&#xff0c;并绘制其数据分布&#xff0c;如下&#xff1a;…

云时代【5】—— LXC 与 容器

云时代【5】—— LXC 与 容器 三、LXC&#xff08;一&#xff09;基本介绍&#xff08;二&#xff09;相关 Linux 指令实战&#xff1a;使用 LXC 操作容器 四、Docker&#xff08;一&#xff09;删除、安装、配置&#xff08;二&#xff09;镜像仓库1. 分类2. 相关指令&#xf…

JavaSE-09(Java IO精华总结)

Java IO 简单做个总结&#xff1a; 1 .InputStream/OutputStream 字节流的抽象类。2 .Reader/Writer 字符流的抽象类。3 .FileInputStream/FileOutputStream 节点流&#xff1a;以字节为单位直接操作“文件”。4 .ByteArrayInputStream/ByteArrayOutputStream 节点流&#xff…

Running job: job_1709516801756_0003

** yarn运行卡在Running job: job_1709516801756_0003问题解决&#xff1a; ** 在运行wordcount时出现错误&#xff0c;一直卡住 运行命令&#xff1a;hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /input /output 出现错误&#xff1a…

岭回归算法

回归分析方法是利用数理统计方法分析数据&#xff0c;建立自变量和因变量间的回归模型&#xff0c;用于预测因变量变化的分析方法。其中比较经典的是HoerI和Kennard提出的岭回归算法。岭回归算法是在最小二乘法的基础上引|入正则项&#xff0c;使回归模型具有较好泛化能力和稳定…

经典思路!人参叶际微生物如何发8分文章?

中国中医科学院中药研究所在《Environmental Microbiome》期刊上(IF7.9)发表了关于叶际真菌微生态网络的文章&#xff0c;该研究通过对ITS测序结果和环境因子测定结果以及皂苷含量测定结果进行生信分析&#xff0c;提出了维持微生态网络的稳定性策略和影响皂苷含量的因素。 期刊…

H12-821_113

113.如图所示是路由器现ATE输出的部分信息&#xff0c;以下关于这部分信息的描述&#xff0c;错误的是哪一项&#xff1f; A.display pim rp-info命令用来查看组播组对应的RP信息 B.RP地址是2.2.2.2 C.组地址是225.0.0.0 D.RP的优先级是0 答案&#xff1a;C 注释&#xff1a; …

HCIA-Datacom题库(自己整理分类的)_29_PPP协议判断【6道题】

1.数据链路层采用PPP封装链路两端的IP地址可以不在同一个网段。√ 2.PPP链路两端不在同一网段不能通信。 3.参考以下拓扑及配置&#xff0c;路由器R1与R2通过Serial低速线缆连接&#xff0c;且数据链路层封装使用PPP。当R1和R2的Holdtime不一致时&#xff0c;PPP协商失败&…

python使用常用的路径问题

PythonPath多个路径的使用 通过命令行直接修改 export PYTHONPATH$PYTHONPATH:/path/to/directoryPythonPath多个路径的使用 export PYTHONPATH$PYTHONPATH:/path/to/directory1:/path/to/directory2PythonPath多个路径的使用 python path 移除路径 python path python中…

爬虫实战——麻省理工学院新闻

文章目录 发现宝藏一、 目标二、 浅析三、获取所有模块四、请求处理模块、版面、文章1. 分析切换页面的参数传递2. 获取共有多少页标签并遍历版面3.解析版面并保存版面信息4. 解析文章列表和文章5. 清洗文章6. 保存文章图片 五、完整代码六、效果展示 发现宝藏 前些天发现了一…

jQuery AJAX get() 和 post() 方法—— W3school 详解 简单易懂(二十四)

jQuery get() 和 post() 方法用于通过 HTTP GET 或 POST 请求从服务器请求数据。 HTTP 请求&#xff1a;GET vs. POST 两种在客户端和服务器端进行请求-响应的常用方法是&#xff1a;GET 和 POST。 GET - 从指定的资源请求数据POST - 向指定的资源提交要处理的数据 GET 基本…

MySQL面试题-日志(答案版)

日志 1、为什么需要 undo log&#xff1f; &#xff08;1&#xff09;实现事务回滚&#xff0c;保障事务的原子性。 事务处理过程中&#xff0c;如果出现了错误或者用户执 行了 ROLLBACK 语句&#xff0c;MySQL 可以利用 undo log 中的历史数据将数据恢复到事务开始之前的状态…