【LeetCode】376. 摆动序列

news2024/11/19 13:30:33

376. 摆动序列

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路

首先,我们可以将摆动序列分为两种:

  • 上升摆动序列」,当且仅当该序列是摆动序列,且最后一个元素呈上升趋势。如序列 [1,3,2,4] 即为「上升摆动序列」。

  • 下降摆动序列」,当且仅当该序列是摆动序列,且最后一个元素呈下降趋势。如序列 [4,2,3,1] 即为「下降摆动序列」。

  • 特别地,对于长度为1的序列,它既是「上升摆动序列」,也是「下降摆动序列」。

状态定义

当我们选择一个元素作为摆动序列的一部分时,它必然会与前一个元素构成上升趋势,或下降趋势。因此,我们可以定义两个数组 up[i]down[i] ,分别表示到位置 i 的元素为止最长的 上升 / 下降 摆动序列的长度。

状态转移

假设 j < i ,那么 nums[i]nums[j] 之间的大小关系存在三种情况:

  • nums[i] > nums[j] :说明 nums[j]nums[i] 会形成上升趋势,所以到位置 i 的元素为止最长的 上升 摆动序列需要更新:到位置 j 的元素为止最长的 下降 摆动序列再加上 nums[i] ,即 up[i] = down[j] + 1;
  • nums[i] < nums[j] :说明 nums[j]nums[i] 会形成下降趋势,所以到位置 i 的元素为止最长的 下降 摆动序列需要更新:到位置 j 的元素为止最长的 上升 摆动序列再加上 nums[i] ,即 down[i] = up[j] + 1;
  • nums[i] = nums[j] :说明 nums[j]nums[i] 没有形成上升或下降的趋势,所以到位置 i 的元素为止最长的 上升/下降 摆动序列都不需要更新,即 down[i] = down[j]; up[i] = up[j];

初始化

根据题目可知,当只有一个元素时,默认它自己形成了摆动序列,长度为1,所以 up[0] = down[0] = 1;

最终的返回结果

由于最后一个元素可能形成上升摆动序列,也可能形成下降摆动序列,所以我们最终需要返回的是两种情况的最大值,即 max(up[n-1], down[n-1]);

代码

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int n = nums.size();
        vector<int> up(n), down(n);

        // 初始化
        up[0] = down[0] = 1;
        
        for(int i=1; i<n; ++i){
            for(int j=0; j<i; ++j){
                // 新的长度至少和之前保持一致
                down[i] = down[j];
                up[i] = up[j];
                if(nums[i] > nums[j]){
                    // 如果新加入的元素大于前一个元素
                    // 则可以在之前的下降子序列基础上变成上升子序列
                    up[i] = down[j] + 1;
                }
                else if(nums[i] < nums[j]){
                    // 如果新加入的元素小于前一个元素
                    // 则可以在之前的上升子序列基础上变成下降子序列
                    down[i] = up[j] + 1;
                }
            }
        }
        return max(up[n-1], down[n-1]);
    }
};

优化一:时间压缩

不难发现, 在遍历到 i 的时候,我们已经知道 i 之前的所有状态,所以只需要考虑 前一种状态即可,可以减少一个循环。

代码

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int n = nums.size();
        vector<int> up(n), down(n);

        // 初始化
        up[0] = down[0] = 1;
        
        for(int i=1; i<n; ++i){
            // 新的长度至少和之前保持一致
            down[i] = down[i-1];
            up[i] = up[i-1];
            if(nums[i] > nums[i-1]){
                // 如果新加入的元素大于前一个元素
                // 则可以在之前的下降子序列基础上变成上升子序列
                up[i] = down[i-1] + 1;
            }
            else if(nums[i] < nums[i-1]){
                // 如果新加入的元素小于前一个元素
                // 则可以在之前的上升子序列基础上变成下降子序列
                down[i] = up[i-1] + 1;
            }
        }
        return max(up[n-1], down[n-1]);
    }
};

优化二:空间压缩

再进一步,由于 up 和 down 都只和前一个状态有关,所以可以使用两个变量来保存。

代码

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int n = nums.size();
        int up = 1, down = 1;
        
        for(int i=1; i<n; ++i){
            if(nums[i] > nums[i-1]){
                // 如果新加入的元素大于前一个元素
                // 则可以在之前的下降子序列基础上变成上升子序列
                up = down + 1;
            }
            else if(nums[i] < nums[i-1]){
                // 如果新加入的元素小于前一个元素
                // 则可以在之前的上升子序列基础上变成下降子序列
                down = up + 1;
            }
        }
        return max(up, down);
    }
};

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

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

相关文章

深度解读:《数字孪生世界白皮书(2023)》全方位剖析

2023年初&#xff0c;中国信息通信研究院发布了《数字孪生城市产业图谱研究报告&#xff08;2022&#xff09;》&#xff0c;报告中提出我国数字孪生产业四阶段体系&#xff0c;2020年到2030年是我国数字孪生产业增长期&#xff0c;当前数字孪生市场需求和技术均处于高速发展阶…

腹部肿瘤内科专家朱利明:化疗也能“订制”,晚期结直肠癌不再“无药可救”

肠癌是发生在结肠和直肠的癌症&#xff0c;近二三十年来发病率快速上升。就在近期&#xff0c;“日本女大胃王菅原初代患肠癌病逝”的消息登上热搜&#xff0c;一时引发网友关注热议。 “人生有哲学三问&#xff1a;我是谁&#xff1f;我从哪里来&#xff1f;我到哪里去&#x…

window下sql-server备份后,拷贝到centos上

一.window下sql-server management 打开本地数据库&#xff0c;点备份 二.拷贝到centos下对应目录 mkdir -p /var/opt/mssql/backup 三.在 Linux 上还原数据库 下列步骤使用 sqlcmd 工具。 如果尚未安装 SQL Server 工具&#xff0c;请按照以下步骤安装&#xff1a; ●(1)用…

DJ5-3/4 中断处理程序和设备驱动程序

目录 5.3 中断机构和中断处理程序 5.3.1 中断简介 5.3.2 中断处理程序 5.4 设备驱动程序 5.4.1 设备驱动程序概述 5.4.2 设备驱动程序的处理过程 5.4.3 对 I/O 设备的控制方式 5.3 中断机构和中断处理程序 5.3.1 中断简介 1、中断和陷入 -- CPU 外部事件和内…

基于C++的通讯管理系统

1、系统需求 通讯录是一个可以记录亲人、好友信息的工具。本教程主要利用C来实现-个通讯录管理系统 系统中需要实现的功能如下: ●添加联系人:向通讯录中添加新人&#xff0c;信息包括(姓名、性别、年龄、联系电话、家庭住址)最多记录1000人 ●显示联系人:显示通讯录中所有联系…

手把手教你搭建ROS阿克曼转向小车之(增量式PID代码实现)

在上一篇文章中我们已经成功的把编码器的反馈值给计算出来&#xff0c;这篇文章将会讲解怎么使用反馈回来的速度值进行PID计算&#xff0c;从而闭环控制电机的速度。 PID算法介绍 1.开环控制系统 开环控制系统(open-loop control system)是指被控对象的输出(被控制量)对控制器…

【软件开发】从单机到分布式

从单机到分布式 1.单台服务器应用 问题&#xff1a;由于流量越来越大出现服务器性能问题。 2.应用服务器和数据库服务器分离 对架构增加了一台服务器&#xff0c;应用和数据库分别部署到不同的服务器上&#xff0c;对于开发和测试没有任何影响&#xff0c;只需要应用服务器新…

画了个 MSP430F149的最小系统板 开源出来了

使用MSP430F149单片机设计的一个最小系统板&#xff0c;包含晶振电路、复位电路、CH340串口和BSL下载电路、按键和LED电路等&#xff0c;使用了Type-C接口作为供电和串口通信&#xff0c;另外引出了JTAG接口&#xff0c;所有IO口都引出了。 板载了3个按键和LED&#xff0c;可以…

项目范围说明书如何编写?

范围说明书是一份定义了项目范围的所有要素以及假设、项目要求和验收标准的文件。项目范围说明书将作为主要工具&#xff0c;供利益相关者和团队成员参考&#xff0c;并作为准确衡量项目成功的准则。 项目范围说明书是范围管理计划的一部分&#xff0c;包含了管理项目范围的所…

百度智能云联合发布《雄安新区2022年大数据研究报告》

近日&#xff0c;百度智能云、百度研究院商业智能实验室联合发布《未来之城 雄姿初显——雄安新区2022年大数据研究报告》&#xff08;以下简称《报告》&#xff09;&#xff0c;运用人工智能和大数据分析技术&#xff0c;全面呈现过去一年雄安新区在承接疏解、生态治理、城市建…

Golang当中的定时器

定时器 前言定时器的基本使用 前言 在平时写代码的时候&#xff0c;我们经常会遇到在将来某个时间点或者间隔一段时间重复执行函数。这个时候我们就可以考虑使用定时器。本片文章主要介绍一下golang当中的几个常用的定时器。time.Timer,time.Ticker,time.After以及time.AfterF…

文鼎创智能物联云原生容器化平台实践

作者&#xff1a;sekfung&#xff0c;深圳市文鼎创数据科技有限公司研发工程师&#xff0c;负责公司物联网终端平台的开发&#xff0c;稳定性建设&#xff0c;容器化上云工作&#xff0c;擅长使用 GO、Java 开发分布式系统&#xff0c;持续关注分布式&#xff0c;云原生等前沿技…

《安富莱嵌入式周报》第311期:300V可调节全隔离USB PD电源,开源交流负载分析仪,CANFD Trace,6位半多斜率精密ADC设计,开源数学库

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版&#xff1a; https://www.bilibili.com/video/BV1Hh4y1H7dR 《安富莱嵌入式周报》第311期&#xff1a;300V可调…

【机器学习】决策树算法解读

【机器学习】决策树算法解读 文章目录 【机器学习】决策树算法解读1. 介绍1.1 优缺点1.2 结构1.3 学习过程1.4 决策树与条件概率分布 2. 决策树学习过程2.1 训练策略2.2 特征选择2.2.1 信息增益和条件熵 2.3 决策树的生成2.3.1 ID32.3.2 C4.52.3.3 CART2.3.4 小结 2.4 决策树的…

Nacos配置中心、配置热更新、及配置共享的记录

Nacos除了提供了注册中心的功能,同样也提供了配置中心的功能,用于管理一些叫常改动的配置 当微服务部署的实例越来越多&#xff0c;达到数十、数百时&#xff0c;逐个修改微服务配置就会让人抓狂&#xff0c;而且很容易出错。我们需要一种统一配置管理方案&#xff0c;可以集中…

计算时间复杂度详解

1&#xff0c;前置知识 我们在计算时间复杂度之前的前置知识是等差数列的通项公式和求和公式以及等比数 列的通项公式和求和公式 等差数列&#xff1a; 通项公式&#xff1a;ana1(n-1)d&#xff08;d是公差&#xff09; 求和公式&#xff1a;Snn(a1an)/2 等比数列&#xf…

【Python入门知识】NumPy数组拆分,超详细讲解

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 今天我们来学习python中NumPy数组的拆分 拆分 NumPy 数组 拆分是连接的反向操作。 连接&#xff08;Joining&#xff09;是将多个数组合并为一个&#xff0c;拆分&#xff08;Spliting&#xff09;将一个数组拆分为多个。…

Mysql 学习(七)独立表结构存储 二

段的结构 上一节说过表空间分为各个段&#xff0c;每个段里面又是以区为单位&#xff0c;每个区则有64个页。区根据剩余存储空间分为&#xff1a;Free&#xff0c;FREE_FRAG&#xff0c;FULL_FRAG 三种类型&#xff0c;为了方便管理区&#xff0c;给每个区创建XDES Entry结构&…

【校招VIP】用户反驳:你说大厂校招不会问框架实战,现在就有问的了,打脸了吧?一看是专业技能给自己挖的坑

最近有个用户过来质疑&#xff0c;不是说大厂不考框架的使用吗&#xff1f; 但网上的这两份面经里&#xff0c;却问到关于SpringBoot的问题。 接着发来了相对应的简历&#xff0c;一看&#xff0c;直接真相大白&#xff1a; 他在专业技能这栏写了&#xff1a;我熟练掌握Sprin…

flink内存参数配置学习

直接上官网 配置 JobManager 内存 | Apache Flink配置 JobManager 内存 # JobManager 是 Flink 集群的控制单元。 它由三种不同的组件组成&#xff1a;ResourceManager、Dispatcher 和每个正在运行作业的 JobMaster。 本篇文档将介绍 JobManager 内存在整体上以及细粒度…