贪心 376. 摆动序列

376. 摆动序列

题目:

连续数字(前减后)的差严格在正负之间交替,差值不能有0为摆动序列。

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

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

(如果只有两个元素,比如[1,2]或者[2,1]也是摆动序列,[1,1]不知道是不是。)

示例 2:

  • 输入: [1,17,5,10,13,15,10,5,16,8]
  • 输出: 7
  • 解释: 这个序列包含几个长度为 7 摆动序列,其中一个可为[1,17,10,13,10,16,8]。

思路:

局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值。比如5 10 13 15,删掉(10,13)剩下5 15

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

推出最长摆动序列后,要求它的最大长度,就是求就是局部峰值的数量。

程序做法 :

假如遍历到 i ,计算 前一个的差值 prediff(nums[i] - nums[i-1]) 和 现在的差值 curdiff(nums[i+1] - nums[i]) ,如果 prediff < 0 && curdiff > 0 或者 prediff > 0 && curdiff < 0 此时就有波动就需要统计。比如17-5-15统计两个波动,1-17-5统计两个波动。

但还有三种情况需要再判断,

1.情况一:上下的坡中有平坡

 比如上图,这个时候2-2-2-2,不是摆动序列,上图的实际摆动序列数量只有3个,可以统一删除左边或者右边3个,这里按删掉左边3个来,删掉后,摆动序列数量3,波动1-2,2-1两个。

变成 (preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0) 记录一次波动,上图相当于preDiff = 0 && curDiff > 0记录了一次,preDiff >= 0 && curDiff < 0记录了一次,总共两次波动,其他的,proDiff=curDiff=0不记录,相当于删去。

2.情况二:数组首尾两端

我的理解是,数组只有两个的情况

比如[2,5],这个时候不能统计它的波动,因为preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0 只能判断有3个数字的,但当只有两个,比如[2,5],题目也判断成摆动数组,题目要 求子序列数组判断为摆动数组后的长度,因为被判定为摆动数组,这里的子序列长度是2

所以这种情况怎么处理,可以直接只有两的时候,比如[2,5]判定成2,也可以不增加特殊条件,默认result(波动记录)加个1,为什么result+1呢?因为相当于[2,5]被扩展成了[2,5,5]

满足了之前条件一更新的的preDiff (<)= 0 && curDiff > 0的这个条件,然后result加了个1

总之就是原来result(波动记录)+1,可以计算数组只有两的情况,满足题目,只有两个的数组为摆动数组,长度为2的要求。(所以为了简洁省特殊条件这样整的麻烦吗...)

经过以上分析,代码如下:

// 版本一
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;}
};
疑问1:

但是网站解析上又说数组首尾两端好像不止包含数组只有两个的情况,还包含数组不单只有两个的情况的左右两端的计算,这个我不太明白。

3.情况三:单调坡度有平坡

 如上版本一的代码在单调坡度有平坡的情况记录了三个波动(确认为摆动),实际上只有2个摆动,为什么会出现这样的情况呢?实时更新了 prediff。

即preDiff = curDiff;在记录波动,即if()外面,

为什么实时更新就会出现这样情况呢?

因为实时更新,如上图,prediff=0 curdiff>0导致原来判断情况1:上下的坡中有平坡的条件错判了情况3:单调坡度有平坡的情况了

怎么解决?

不再实时更新,而是当这个坡度 摆动变化的时候,才更新 prediff ,这样单调坡度的时候就不会出现误判情况3:单调坡度有平坡的情况了

所以为什么这样一改就可以了呢?坡度有变化又是什么意思?

坡度有变化指,满足(preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)的条件,result(波动记录)++的时候,没改前会记录上图2-2-2的这个节点,改了后,不会记录这个点,因为从第一个1到2的时候,2往后走就不更新了,一直是prediff>0的状态,这个时候到中间那个2-2-2,就不会更新,因为没更新prediff>0,curdiff>0不满足条件不更新。

总代码:

// 版本二
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; // 注意这里,只在摆动变化的时候更新prediff}//上一行是和版本一的差别,从外面挪里面了}return result;}
};

总结下就是,序列要满足最长摆动序列的条件的话,就需要求最多的波动点(峰值),而波动点的总值就是序列的子序列and最长摆动序列的长度值。然后有三个不同的条件影响,单调中平坡,上下的坡中平坡,以及强制要求情况,数组首尾两端。

整完后和我想的不一样,3h10min

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

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

相关文章

Docker监控Weave Scope的安装和使用

1.本地安装Weave Scope 1&#xff09;创建文件夹。 mkdir /usr/local/bin/scope 2&#xff09;从本地上传文件。 rz scope.bin以资源形式已上传到文章开篇。 3&#xff09;修改scope.bin文件为可执行文件。 chmod 755 /usr/local/bin/scope/scope.bin 4&#xff09;执行sco…

AntDB数据库:从海量数据处理,到5G计费商用核心

AntDB数据库自2008年研发面世以来&#xff0c;首先被应用于运营商的核心系统&#xff0c;满足运营商海量数据处理的需求。随着数字科技的不断发展&#xff0c;AntDB也在不断地更新迭代&#xff0c;逐渐地为更多行业与客户提供更全面的服务。5G时代来临&#xff0c;AntDB抓住发展…

《微信小程序开发从入门到实战》学习三十六

4.2 云开发JSON数据库 4.2.6 云开发JSON数据库 在集合对象上调用add方法可以在集和中可以插入一条记录&#xff0c;代码如下&#xff1a; db.collection(testOne).add({ // 在JSON数据库的testOne集合中增加一个记录 data:{ name: "write paper" }, // 插入数据成功…

华住三季报:韧性增长超预期,夯实可持续发展底座

美股研究社获悉&#xff0c;2023年11月27日&#xff0c;华住集团2023年第三季度业绩发布会在线上举行。受华住三季度财报向好表现&#xff0c;多家证券公司给予买入评级。中信证券认为&#xff0c;本季度华住集团国内外RevPAR修复优于前期指引上限、净开店数优于预期。且华住集…

如何手工获取并更新ESXi中macOS的VMware Tools版本

正文共&#xff1a;1128 字 22 图&#xff0c;预估阅读时间&#xff1a;1 分钟 前面我们介绍了如何在VMware ESXi创建macOS虚拟机&#xff08;VMware ESXI部署macOS Monterey&#xff09;&#xff0c;也大概介绍了如何安装VMware Tools&#xff0c;因为VMware Tools可以提供对虚…

一名技术Leader应该是创作者

今天看了一本书叫做《黑客与画家》。它里面提到一个很重要的概念就是黑客&#xff08;优秀的程序员&#xff09;是一名建筑师&#xff0c;而不是一名工程师。 传统的主管和互联网的Leader 这两者有什么区别呢&#xff1f;关键点在于建筑师是思考做什么&#xff0c;而工程师是…

超实用电脑技巧分享,快速提高工作效率!

“我是个刚开始学习使用电脑的新手&#xff0c;想问问大家有什么比较好用的电脑使用技巧可以推荐一下吗&#xff1f;非常感谢&#xff01;” 在使用电脑时&#xff0c;如果我们适当掌握一些技巧&#xff0c;可以有效提高效率。那么&#xff0c;今天小编就给大家分享一些常见的电…

前五年—中国十大科技进展新闻(2012年—2017年)

前五年—中国十大科技进展新闻&#xff08;2012-2017&#xff09; 2017年中国十大科技进展新闻1. 我国科学家利用化学物质合成完整活性染色体2. 国产水下滑翔机下潜6329米刷新世界纪录3. 世界首台超越早期经典计算机的光量子计算机诞生4. 国产大型客机C919首飞5. 我国首次海域天…

leetcode:用栈实现队列(先进先出)

题目描述 题目链接&#xff1a;232. 用栈实现队列 - 力扣&#xff08;LeetCode&#xff09; 题目分析 我们先把之前写的数组栈的实现代码搬过来 用栈实现队列最主要的是实现队列先进先出的特点&#xff0c;而栈的特点是后进先出&#xff0c;那么我们可以用两个栈来实现&…

盖茨表示GPT-5不会比GPT-4有太大改进;Intro to Large Language Models

&#x1f989; AI新闻 &#x1f680; 盖茨表示GPT-5不会比GPT-4有太大改进 摘要&#xff1a;比尔盖茨在与德国《商报》的采访中透露&#xff0c;虽然OpenAI内部有人相信GPT-5会优于GPT-4&#xff0c;但他认为目前的生成式人工智能已经达到极限。盖茨对GPT-5未来的发展并不乐观…

麒麟操作系统光盘救援模式

麒麟操作系统光盘救援模式 Kylin V4 桌面版&#xff1a; 启动主机后&#xff0c;插入系统光盘&#xff0c;在 BIOS 启动项里设置成从光盘启动后保存退出重启主机。 稍等片刻就会到启动菜单选项&#xff0c;到启动菜单界面后选择第一项试用银河麒麟操作系统而不安 装&#xff…

一个人撸码!之vue3+vite+element-plus后台管理(标签页组件)

一个后台管理常常需要一个标签页来管理已经打开的页面&#xff0c;这里我们单独写一个组件来展示标签页数组。 该标签页组件只做展示不涉及操作数据。标签页数组可记录已打开的数组&#xff0c;还能定义什么页面需要缓存&#xff0c;是一个重要的功能呢。 首先&#xff0c;建立…

Java(九)(多线程,线程安全,实现线程的方法,线程同步,线程池,并发和并行,线程的六种状态)

目录 多线程 线程 实现线程的方法 方法一:继承Thread父类 方法二:实现Runnable接口 方法三:Callable接口和FutureTask类来实现 Thread方法 线程安全 线程同步 同步代码块 同步方法 Lock锁 线程池 线程池对象的创建方式一: 线程池处理Runnable任务 线程池处理Cal…

BGP综合实验

任务如下&#xff1a; 1.AS1存在两个环回&#xff0c;一个地址为192.168.1.0/24该地址不能在任何协议中宣告 AS3存在两个环回&#xff0c;一个地址为192.168.2.0/24该地址不能在任何协议中宣告&#xff0c;最终要求这两个环回可以互相通讯 2.整个AS2的IP地址为172.16.0.0/16&…

Sentaurus TCAD半导体器件入门常用案例合集

Sentaurus TCAD是用于模拟半导体器件和工艺的工具之一&#xff0c;可以帮助工程师设计电路元件&#xff0c;优化半导体工艺和器件性能。主要功能包括&#xff1a;半导体器件建模&#xff08;用于建立各种半导体器件的物理模型工艺模拟&#xff09;、半导体器件的制造工艺模拟&a…

Debian10安装VMware Tools

一、原系统 首先我在界面按CTRLALTT和CTRLSiftT都没有反应&#xff0c;没关系&#xff0c;我有办法 系统版本 管理员用户 步骤一&#xff1a;打开VMware Tools文件 步骤二、将文件复制到自己熟悉的文件内 步骤三、命令行查看文件是否复制成功存在 步骤四、解压VMware-tools…

宋仕强论道之华强北的商业配套(十三)

宋仕强论道之华强北的商业配套&#xff08;十三&#xff09;&#xff1a;金航标电子萨科微半导体总经理宋仕强先生发布“宋仕强论道”系列视频&#xff0c;分享多年学习、生活和工作经验和感悟&#xff0c;甚至涵盖了文学、艺术、哲学、宗教。这段时间发表的是对华强北&#xf…

程序设计基础中可能出现的简单编程题2(以郑大为主体)

我们在学习编程过程中往往不仅有C语言实验报告&#xff0c;还有程序设计实验报告。程序设计这一科目主要是为了培养我们写代码时的计算思维&#xff0c;养成从问题到代码实现逐步分析&#xff0c;逐步深入的好习惯。前面有一篇文章介绍了部分程序设计实验报告中的编程题&#x…

第二十章 -----多线程

20.1 线程简介 计算机完全可以将多种活动同时进行&#xff0c;这种思想在java中称为并发&#xff0c;将并发完成的每一件事情称为线程 线程的特点&#xff1a; 极小的单位 一个进程有很多个线程 线程共享进程的资源 20.2 创建线程 20.2.1 继承Thread类 Thread类是Java.l…

Python实现视频人脸检测识别功能

目录 一、引言 二、人脸检测识别技术概述 三、Python实现视频人脸检测识别功能的步骤 1、安装相关库和工具 2、加载视频文件 3、人脸检测和识别 4、保存视频结果 四、实验结果和讨论 五、结论 一、引言 在当今社会&#xff0c;人脸检测识别技术在安全监控、人机交互、…