(贪心) LeetCode 376. 摆动序列

news2024/12/29 14:31:49

原题链接

一. 题目描述

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

例如, [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 <= nums.length <= 1000
0 <= nums[i] <= 1000
 

进阶:你能否用 O(n) 时间复杂度完成此题?

二. 解题思路

这个题目的意思就是让我们寻找最长的摆动序列,连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列。如果之间有数字不构成摆动序列,那么就可以删除一些元素从而让序列摆动。

题意很简单,但是做起来不知道怎么写?你难道真的准备判断是否摆动,然后遇到不是摆动序列的元素删除它吗?不不不,跳过不就好了,题目没有明确要求必须删除元素,我们只需要跳过该元素判断后面的元素是否摆动即可,最后只需要输出摆动序列的最长长度即可。

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

下面可以将情况分为三种:

1. 上下坡中存在平坡:

 像这种类型的我们只需要从左到右或者从右到左删除三个2就可以构成摆动序列了(如下图所示):

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

所以我们记录峰值的条件应该是: (predif <= 0 && curdif > 0) || (predif >= 0 && curdif < 0),为什么这里允许 prediff == 0 ,就是为了 上面的这种情况。

2. 数组的首尾两端:

大家可以发现,我们在上面计算predif 和curdif 的时候至少需要三个元素才能完成计算,那要是序列中只有两个元素呢?如[1, 2],题目中明确要求,如果两个元素,存在两个摆动。那我们怎么将这种情况算到上面的哦按段条件中呢?

很简单,只需要给序列的首元素添加一个平坡即可(如下图所示),将序列[2, 5] 变为 [2, 2, 5]:

 这样也就对 predif 就可以计算为 0 ,那末尾怎么算呢?其实我们末尾默认是有一个峰值的,所以我们将结果集 res 默认为 1 即可。这样就可以得到最后的 res 为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;
    }
};

3. 单调坡度有平坡:

什么叫单调坡度有平坡呢,看下图就可以明白了:

从上图中大家觉得答案是多少, 应该是2,但是我们如果按照上面的代码计算方法会算出来3 ,显然是不对的,为什么呢,原因就是我们每一次都会将curdif 赋值给 predif ,但是遇到这种情况的平坡的时候,在最后一个2 处 predif = 0,然后后面计算的 curdif = 1。满足上面的判断条件,就会多加一次,实际上这里不存在摆动,这也就是我们代码中的一个逻辑性的错误。

对于解决上面的错误方法很简单,只需要将 predif = curdif 这个赋值代码加入到判断条件内部即可,保证摆动的前提是相较于上一次的摆动,而不是最近区间的摆动,这样prediff 在 单调区间有平坡的时候 就不会发生变化,从而避免误判。

话不多说!!!上代码!!

三. 代码

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

四. 总结

这个题目还是比较绕的,需要考虑很多种情况,我感觉是比较难的一道题目,刚开始做的时候确实有点难懂,但是大家一定要多去看,多去理解,在本子上列举情况去分析,这样才能有进步,加油!!!。

时间复杂度:O(n);

空间复杂度:O(1)。

喜欢的话给个关注吧!!

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

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

相关文章

电脑技巧:电脑系统盘文件清理指南

目录 一、可以安全删除的文件 1.1. 临时文件 1.2. 系统缓存文件 1.3. 回收站 1.4. 安装包缓存 1.5. 系统还原点 1.6. 已下载的更新文件 1.7. 浏览器缓存 1.8. Thumbs.db 文件 1.9. Windows日志文件 1.10. Windows.old 文件夹 二、系统文件清理注意点 三、系统文件…

推荐一款Python开源移动应用安全测试分析工具!!!

今天给大家推荐一个安全测试相关的开源项目&#xff1a;nccgroup/house 1、介绍 它是一个由 NCC Group 开发的&#xff0c;一个基于Frida和Python编写的动态运行时移动应用分析工具包&#xff0c;提供了基于 Frida 的 Web GUI 界面&#xff0c;旨在简化动态函数挂钩的过程&am…

Linux---04---Vim编辑器

一、vi/vim编辑器介绍 vi 是 visual interface 的简称&#xff0c;是Linux系统提供的一个文本编辑工具&#xff0c;可以对文件内容进行编辑&#xff0c;类似于Windows中的记事本。 vim 是 vi 的加强版本&#xff0c;兼容 vi 的所有指令&#xff0c;不仅能编辑文本&#xff0c…

Using locally deployed llm with langchain‘s openai llm wrapper

题意&#xff1a;使用本地部署的LLM与Langchain的OpenAI LLM封装器 问题背景&#xff1a; I have deployed llm model locally which follows openai api schema. As its endpoint follows openai schema, I dont want to write separate inference client. 我已经本地部署了…

Mybatis框架介绍

Mybatis入门 MyBatis 是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO&#xff08;Plain Old Jav…

IT管控体系建设(集团企业),附网传埃森哲案例

&#xff08;一&#xff09;集团IT企业IT管控组织结构设计 1.集团分管领导 职能&#xff1a;最高级别的管理&#xff0c;负责对整个集团的信息化管控进行监督和决策。 2.CIO/管理部主任 职能&#xff1a;负责整体的IT战略和方向&#xff0c;直接向集团分管领导汇报。负责协…

一分钟了解:Java 冒泡排序算法

1. 冒泡排序算法介绍 冒泡排序是最简单的排序算法&#xff0c;如果相邻元素的顺序错误&#xff0c;则通过反复交换相邻元素来工作。Java 中的冒泡排序不是对数组进行排序的最佳方法&#xff0c;但却是最基本的实现之一。在本文中&#xff0c;我们将学习如何用 Java 编写冒泡排…

「Pytorch」解析 nn.Embedding 词嵌入 及反推输入

在Pytorch里面有三种编码方式&#xff0c;Embedding 就是其中之一&#xff0c;不同于 one_hot 需要用同长度的张量存 Embedding将单词映射为稠密向量&#xff0c;并且指定 embedding_dim维度。通过 Embedding层 转换的数据并不是经过词典映射的&#xff0c;而是原始数据。Embed…

VirtualBox扩容VDI虚拟磁盘

环境 虚拟机软件&#xff1a;VirtualBox虚拟机&#xff1a;Ubuntu 18.04.1 第一步&#xff1a;调整虚磁盘大小 方法1&#xff1a;使用VirtualBox管理器直接修改 关闭虚拟机&#xff0c;点击VirtualBox管理器菜单管理>虚拟介质管理&#xff0c;重新设大小 方法2&#x…

【Linux基础】对Linux权限的理解与管理

目录 &#x1f680;前言一&#xff0c;有关用户二&#xff0c;Linux权限管理1. 文件访问者的分类(人)2. 文件类型和访问权限(事物属性)2.1 文件类型2.2 文件/目录的基本权限 三&#xff0c;文件权限值的表示方法3.1 字符表示方法3.2 八进制数值表示方法 四&#xff0c;文件访问…

服务器是什么?怎么选择适合自己的服务器?

在这个数字化的世界中&#xff0c;我们每天都在与各种网站打交道&#xff0c;浏览新闻、购物、看视频等。你是否曾经好奇过&#xff0c;这些网站是如何运行的&#xff1f;它们又是如何实现随时随地可访问的呢&#xff1f; 在这背后&#xff0c;有一个神秘的角色在默默地支撑着…

数据结构与算法 - 贪心算法

一、贪心例子 贪心算法或贪婪算法的核心思想是&#xff1a; 1. 将寻找最优解的问题分为若干个步骤 2. 每一步骤都采用贪心原则&#xff0c;选取当前最优解 3. 因为没有考虑所有可能&#xff0c;局部最优的堆叠不一定让最终解最优 贪心算法是一种在每一步选择中都采取在当前…

letcode 分类练习 树的遍历

letcode 分类练习 树的遍历 树的构建递归遍历前序遍历中序遍历后序遍历 迭代遍历前序遍历中序遍历后序遍历 层序遍历层序遍历可以解决的问题107. 二叉树的层序遍历 II199. 二叉树的右视图637. 二叉树的层平均值429. N 叉树的层序遍历515.在每个树行中找最大值116.填充每个节点的…

掌机系统MuOS游戏名称中文乱码解决主题

最近买了安伯尼克的rg35xxh掌机来玩儿&#xff0c;然后刷了muos&#xff0c;系统很小巧&#xff0c;1g的运行内存&#xff0c;系统运行的时候只占用了不到100m&#xff0c;而且界面也很美观&#xff0c;就是有一个问题——中文名称会乱码&#xff0c;都变成了方框&#xff0c;从…

如何给IP地址开启https—IP证书

先IP地址申请的前提&#xff1a;80端口有打开&#xff0c;或者可以短暂的打开10分钟左右等验证完IP管理权再关掉。 一&#xff1a;访问JoySSL官网&#xff0c;注册账号并填写注册码230922&#xff0c;选择IP地址证书并下单加入购物车&#xff0c;下单之后就会跳转到证书申请界…

Linux--应用层协议HTTP协议(http服务器构建)

目录 1.HTTP 协议 2.认识 URL 3.urlencode 和 urldecode&#xff08;编码&#xff09; urlencode&#xff08;URL编码&#xff09; urldecode&#xff08;URL解码&#xff09; 4.HTTP 协议请求与响应格式 4.1HTTP 常见方法&#xff08;三种&#xff09; 5.HTTP 的状态码…

C++:命名空间与输入输出

目录 前言 一、命名空间 1.1 namespace的价值 1.2 namespace的定义 1.3 命名空间的使用 二、C输入&输出 前言 C是一种面向对象的计算机程序设计语言&#xff0c;‌它扩展了C语言的功能&#xff0c;‌并引入了面向对象编程的概念&#xff0c;‌如类、‌继承和多态等&a…

【笔记】从零开始做一个精灵龙女-画贴图阶段(下)

补充四点&#xff0c;第一&#xff0c;前期画体积用一号或十三号笔刷&#xff0c;压力60&#xff0c;硬度80&#xff0c;体积大一点 2号笔刷比较适合画过渡和软一点的东东 第二&#xff0c; 游戏里面角色原画海报都是发光很亮很透。但是在bp不能画那么亮&#xff0c;因为你进…

git强制推送代码教程

git强制推送代码教程 首先说明情况&#xff0c;我的代码remote了两个git库&#xff0c;现在想要推送到其中一个&#xff0c;但是版本不对&#xff0c;被拒绝&#xff0c;因此下面将进行强制推送 首先检查远程库都有哪些 git remote -v2. 检查当前的分支 git branch当前分支前…