leetCode 376.摆动序列 贪心算法

news2024/11/23 9:36:32

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

  • 例如, [1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。

  • 相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。

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

示例 1:

输入:nums = [1,7,4,9,2,5]
输出:6
解释:整个序列均为摆动序列,各元素之间的差值为 (6, -3, 5, -7, 3) 。

示例 2:

输入:nums = [1,17,5,10,13,15,10,5,16,8]
输出:7
解释:这个序列包含几个长度为 7 摆动序列。
其中一个是 [1, 17, 10, 13, 10, 16, 8] ,各元素之间的差值为 (16, -7, 3, -3, 6, -8) 。

示例 3:

输入:nums = [1,2,3,4,5,6,7,8,9]
输出:2

>>思路和分析

思路1:贪心思路

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

试试贪心:局部最优推出全局最优,并举不出反例!!!

实际操作上,可以不用做删除操作,由于题目要求的是最长摆动子序列的长度,所以只需要统计数组的局部峰值数量就可以了(相当于是删除单一坡度上的节点,然后统计长度)这也就是贪心所贪的地方。

(1)如何表示一个波动呢?

curdiff = nums[i+1] - nums[i];
prediff = nums[i] - nums[i-1];

如果prediff < 0 && curdiff > 0 或者 prediff > 0 && curdiff < 0 此时就有波动就需要统计

(2)如果出现平坡又该如何解决呢? 我们继续往下看~

平坡有两种:一个是 上下中间有平坡,一个是 单调中间有平坡 

① 情况一:上下坡中有平坡

例如 [1,2,2,2,1],它的摆动序列长度是3,也就是我们在删除的时候要不删除左面的三个2,要不就删除右面的三个2

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

若采用删除左面三个2的规则,那么 当 i 指向第一个2的时候,prediff = 0 && curdiff < 0,也要记录一个峰值。这是由于它是把之前相同的元素都删除留下的峰值

所以这里记录峰值的条件可以允许prediff = 0,也就是:prediff <= 0 && curdiff > 0 或者 prediff >= 0 && curdiff < 0 。也就是说相同数字连续的时候,prediff = 0,curdiff < 0 或者 >0 也就为波谷

② 情况二:数组首尾两端

问题思考(O_O)? 统计峰值时,数组的最左面和最右面如何统计呢?

例子:序列[2,5],摆动序列为2。

上文提到 prediff = nums[i] - nums[i-1] 和 curdiff = nums[i+1] - nums[i] 的时候,可知至少需要三个数字才能计算。因其靠统计差值来计算峰值个数就需要考虑数组最左面和最右面的特殊情况。而此时序列数组只有两个数字,如何将我们的判断规则结合在一起呢?

不妨假设数组前面还有一个数字,也就是将序列[2,5],假设为[2,2,5],此时这就有了坡度prediff = 0。而这正是上文讨论的情况一,那么也可以记为一个波谷

针对以上情况,result 初始为 1 (默认最右面有一个峰值),此时curdiff > 0 && prediff <= 0 ,那么result++ (计算了左面的峰值),最后得到的 result 就是 2(峰值个数是2,也就是摆动序列长度为2)

所以说可以初始化 prediff = 0,result = 1

③ 情况三:单调坡中有平坡

上图中,可以计算峰值结果为3,但其实结果应该为2。这是因为上图是不加限制的实时更新prediff,这会导致 单调中的平坡被算为峰值

什么时候该更新prediff呢?只需要在这个坡度摆动变化的时候,更新prediff就行,这样prediff在单调区间有平坡的时候,就不会发生变化,也就不会产生误判!

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if(nums.size() <= 1) return nums.size();
        int prediff = 0; // 前一对差值
        int curdiff = 0; // 当前一对差值
        int result = 1; // 记录峰值个数,序列默认序列最右边有一个峰值
        for(int i=0;i<nums.size()-1;i++) {
            curdiff = nums[i+1] - nums[i];
            // prediff=curdiff放在if里面,为的是处理单调有平坡的这种情况
            if((prediff >=0 && curdiff<0) || (prediff <=0 && curdiff>0)) { // 出现峰值
                result++;
                prediff = curdiff; // 注意这里,只在摆动变化的时候更新prediff
            }
        }
        return result;
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

prediff = curdiff 放在 if 里面,为的是处理单调有平坡的这种情况。若放在 if 外面,则会出现上文所述的误判!!!

参考和推荐文章、视频

代码随想录 (programmercarl.com)

贪心算法,寻找摆动有细节!| LeetCode:376.摆动序列_哔哩哔哩_bilibili

来自代码随想录的课堂截图:

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

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

相关文章

AI智能问答系统源码/AI绘画商业系统/支持GPT联网提问/支持Midjourney绘画

一、AI创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的AI智能问答系统和AI绘画系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图…

.360、.halo勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复

导言&#xff1a; 在网络犯罪的阴影下&#xff0c;.360和.halo勒索病毒显得格外神秘而危险&#xff0c;它们都属于BeijingCrypt勒索病毒家族旗下的病毒&#xff0c;两者加密特征一致&#xff0c;加密勒索信内容一致。本文91数据恢复将深度解析.360、.halo勒索病毒的内部机制&a…

【算法速查】一篇文章带你快速入门八大排序(上)

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;首先在这里祝大家中秋国庆双节同乐&#xff01;&#xff01;今天用一篇文章为大家把八大排序算法都过一遍&#xff0c;当然由于篇幅的原因不是每…

华为云云耀云服务器L实例评测|Ubuntu系统MySQL 8.1.0 Innovation压测

文章目录 前言&#x1f4e3; 1.前言概述&#x1f4e3; 2.云服务器性能监控&#x1f4e3; 3.MySQL8.1版本安装✨ 3.1 安装包下载✨ 3.2 解压安装包✨ 3.3 登录验证 &#x1f4e3; 4.ubuntu安装sysbench&#x1f4e3; 5.云服务器压测✨ 5.1 IO测试✨ 5.2 CPU性能测试 &#x1f4e…

React18+Ts项目配置husky、eslint、pretttier、commitLint

前言 我的项目版本如下&#xff1a; React&#xff1a; V18.2.0Node.js: V16.14.0TypeScript&#xff1a;最新版工具&#xff1a; VsCode 本文将采用图文详解的方式&#xff0c;手把手带你快速完成在React项目中配置husky、prettier、commitLint&#xff0c;实现编码规范的统…

Javaweb作业小结

简单的XML文档 用JS求连乘积 function product(N) { let p 1; for (let i 1; i < N; i) { p * 2 * i - 1; } return p; } // 调用函数并输出结果 const N 7; // 这里的 N 是你想要的奇数的个数 const result product(N); console.log(p ${result}); Servlet映射关系…

动态规划:两个数组的dp问题(C++)

动态规划&#xff1a;两个数组的dp问题 前言两个数组的dp问题1.最长公共子序列&#xff08;中等&#xff09;2.不同的子序列&#xff08;困难&#xff09;3.通配符匹配&#xff08;困难&#xff09;4.正则表达式&#xff08;困难&#xff09;5.交错字符串&#xff08;中等&…

Go结构体深度探索:从基础到应用

在Go语言中&#xff0c;结构体是核心的数据组织工具&#xff0c;提供了灵活的手段来处理复杂数据。本文深入探讨了结构体的定义、类型、字面量表示和使用方法&#xff0c;旨在为读者呈现Go结构体的全面视角。通过结构体&#xff0c;开发者可以实现更加模块化、高效的代码设计。…

背包问题

目录 开端 01背包问题 AcWing 01背包问题 Luogu P2925干草出售 Luogu P1048采药 完全背包问题 AcWing 完全背包问题 Luogu P1853投资的最大效益 多重背包问题 AcWing 多重背包问题 I AcWing 多重背包问题 II Luogu P1776宝物筛选 混合背包问题 AcWing 混合背包问题…

JavaSE学习之--抽象类和接口

&#x1f495;"没有眼泪我们就会迷路&#xff0c;彻底变成石头&#xff0c;我们的心会变成冰凌&#xff0c;吻会变成冰块。"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;JavaSE学习之--抽象类和接口 一.抽象类 1.抽象类的定义 我们知道&#x…

数仓精品理论-做大数据还有没有前途?

数仓精品理论-做大数据还有没有前途&#xff1f; 做大数据还有没有前途&#xff1f;大数据三要三不要我来讲讲大数据前景 做大数据还有没有前途&#xff1f; 先说&#xff0c;答案是肯定的&#xff0c;但一定要记住三要三不要。 datapulse官网&#xff1a; github:https://data…

cesium gltf控制

gltf格式详解 glTF格式本质上是一个JSON文件。这一文件描述了整个3D场景的内容。它包含了对场景结构进行描述的场景图。场景中的3D对象通过场景结点引用网格进行定义。材质定义了3D对象的外观,动画定义了3D对象的变换操作(比如选择、平移操作)。蒙皮定义了3D对象如何进行骨骼…

黑豹程序员-架构师学习路线图-百科:HTML-网页三剑客

为什么需要HTML 在网站技术发达之前&#xff0c;千年来我们获取信息是通过书籍。电脑流行后我们看文章、小说通过txt文件。看图通过单独的图片流量工具看单个的图片文件。 而HTML把文字和图片一起展示&#xff0c;让今天的电子书成为可能。 另外一点&#xff0c;我们的信息是…

【操作系统】了解Linux操作系统中PCB进程管理模块与进程PID

本篇要分享的内容是有关于操作系统中进程的内容。 目录 1.进程的简单理解 2.了解task_struct&#xff08;进程控制模块&#xff09;内容分类 3.task_struct&#xff08;进程控制模块&#xff09;中的PID 4.调用查看PID的函数 1.进程的简单理解 首先我们需要理解的是什么是…

简单讲解 glm::mat4

文章目录 前言一、下载glm库二、基本数学知识1. 三维中的 4 x 4 矩阵2.旋转3. 位移4. 缩放5. 组合 三、行向量或列向量四、总结 前言 glm库是OpenGL的官方数学库&#xff0c;里面内置多种跟几何变换相关的函数&#xff0c;熟练掌握glm库可以省下很多麻烦。 因为最近在项目中主…

鞋类 整鞋试验方法 剥离强度

声明 本文是学习GB-T 3903.3-2011 鞋类 整鞋试验方法 剥离强度. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 GB/T 3903 的本部分规定了整鞋鞋底与鞋帮或外底与外中底之间剥离强度的试验方法。 本部分适用于采用模压、硫化、注塑、灌注、胶…

暴力破解及验证码安全

1.暴力破解注意事项 1、破解前一定要有一个有郊的字典&#xff08;Top100 TOP2000 csdn QQ 163等密码&#xff09; https://www.bugku.com/mima/ 密码生成器 2、判断用户是否设置了复杂的密码 在注册页面注册一个,用简单密码看是否可以注册成功 3、网站是…

Jenkins集成AppScan实现

一、Jenkins上安装插件 在Jenkins里安装以下插件 ibm-security-appscanstandard-scanner 二、打开AppScan 1、配置需要扫描的地址 配置需要扫描的地址 2、记录好要扫描的URL登录序列 记录好要扫描的URL登录序列 3、导出要扫描的URL登录序列设置 导出要扫描的URL登录序列设置 三…

C程序设计内容与例题讲解 -- 第四章--选择结构程序设计(第五版)谭浩强

前言&#xff1a;在第三章我们介绍了顺序结构程序设计。在顺序结构中&#xff0c;各个语句是按自上而下的顺序执行的&#xff0c;执行完上一个语句就自动执行下一个语句&#xff0c;是无条件的&#xff0c;不必做任何判断。是这最简单的程序结构。实际上&#xff0c;在很多情况…

IDEA 配置 Maven(解决依赖下载缓慢)

IDEA 配置 Maven&#xff08;解决依赖下载缓慢&#xff09; 这一篇主要介绍 Maven 的基本用法。等我之后学习到框架知识时&#xff0c;会完善此部分内容。 一、Maven 简介 Maven 是专门用于管理和构建 Java 项目的工具&#xff0c;Apache Maven 是一个项目管理和构建工具&#…