一、题目

如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。例如, [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 <= 10000 <= nums[i] <= 1000

二、思路

  • 第一种思路: d p [ i ] [ 0 ] dp[i][0] dp[i][0]代表以i结尾的数小于子序列前面一个数, d p [ i ] [ 1 ] dp[i][1] dp[i][1]代表以i结尾的数大于子序列前面一个数。那么利用上升子序列的思路,若当前数 n u m s [ i ] < n u m s [ j ] nums[i] < nums[j] nums[i]<nums[j],那么可以由 d p [ j ] [ 1 ] dp[j][1] dp[j][1]转移而来, d p [ j ] [ 1 ] dp[j][1] dp[j][1]代表以j结尾的子序列且nums[j]大于它所在的子序列的前一个数,那么新添加的nums[i]再小于nums[j]即构成摆动序列。 n u m s [ i ] > n u m s [ j ] nums[i] > nums[j] nums[i]>nums[j]同理。 时间复杂度 O ( n 2 ) O(n^2) O(n2) 空间复杂度 O ( n ) O(n) O(n)
  • 第二种思路动态规划优化: d p [ i ] [ 0 ] dp[i][0] dp[i][0]: 代表前i个元素组成的子序列是最后是上升的最大长度, d p [ i ] [ 1 ] dp[i][1] dp[i][1]: 代表前i个元素组成的子序列是最后是下降的最大长度。若 n u m s [ i ] > n u m s [ i − 1 ] nums[i] > nums[i - 1] nums[i]>nums[i−1],代表表可以由前一个下降转化为上升 或者 用nums[i]替换nums[i - 1]作为上升序列即 d p [ i ] [ 0 ] = m a x ( d p [ i − 1 ] [ 1 ] + 1 , d p [ i − 1 ] [ 0 ] ) ; dp[i][0] = max(dp[i - 1][1] + 1, dp[i - 1][0]); dp[i][0]=max(dp[i−1][1]+1,dp[i−1][0]); 继续保留以前的长度,即 d p [ i ] [ 1 ] = d p [ i − 1 ] [ 1 ] dp[i][1] = dp[i - 1][1] dp[i][1]=dp[i−1][1] 时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( n ) O(n) O(n),可以将dp优化为变量后为O(1)
  • 第三种思路贪心:我们不断用可以替换的值替换前面的以获取最优的序列,如 1 2 3 4, 我们可以获得子序列为 [ 1 , 2 ] [ 1 , 3 ] , [ 1 , 4 ] [1, 2] [1, 3], [1,4] [1,2][1,3],[1,4] 直接用最大的4替换前面的2,3这样可以保证如果后面有更小的数可以进行下降操作,同理4 3 2 1 也是如此,不断用小的数替换前面满足要求的,这样后面遇到更大的数可以组合成上升序列。

三、代码

class Solution {public:int wiggleMaxLength(vector<int>& nums) {int n = nums.size(), ans = 1;//dp[i][0]: 代表以i结尾的数小于子序列前面一个数//dp[i][1]: 代表以i结尾的数大于子序列前面一个数vector<vector<int>> dp(n, vector<int>(2, 1));for (int i = 1;  i < n ; i++) {for (int j = 0; j < i; j++) {if (nums[i] < nums[j]) {dp[i][0] = max(dp[j][1] + 1, dp[i][0]);} else if (nums[i] > nums[j]) {dp[i][1] = max(dp[j][0] + 1, dp[i][1]);}}ans = max(max(dp[i][0], dp[i][1]), ans);}return ans;}
};
class Solution {public:int wiggleMaxLength(vector<int>& nums) {int n = nums.size(), ans = 1;//dp[i][0]: 代表前i个元素组成的子序列是最后是上升的最大长度//dp[i][1]: 代表前i个元素组成的子序列是最后是下降的最大长度vector<vector<int>> dp(n, vector<int>(2, 1));dp[0][0] = dp[0][1] = 1;for (int i = 1;  i < n ; i++) {if (nums[i] > nums[i - 1]) {//代表表可以由前一个下降转化为上升 或者 用nums[i]替换nums[i - 1]作为上升序列dp[i][0] = max(dp[i - 1][1] + 1, dp[i - 1][0]);//继续保留以前的长度dp[i][1] = dp[i - 1][1];} else if (nums[i] < nums[i - 1]) {dp[i][0] = dp[i - 1][0];dp[i][1] = max(dp[i - 1][0] + 1, dp[i - 1][1]);} else {//等于的情况 直接由前面转移dp[i][0] = dp[i - 1][0];dp[i][1] = dp[i - 1][1];}}return max(dp[n - 1][0], dp[n - 1][1]);}
}; 
class Solution {public:int wiggleMaxLength(vector<int>& nums) {int n = nums.size(), ans = 1, t = nums[0];for (int i = 1; i < n; i++) {if (nums[i] > t) {//一直挑选大的while (i < n && nums[i] >= t) {t = nums[i];i++;}i--;ans++;} else if(nums[i] < t) {while (i < n && nums[i] <= t ) {t = nums[i];i++;}i--;ans++;}}return ans;}
};

LeedCode 376. 摆动序列相关推荐

  1. LeetCode 376. 摆动序列 中等难度

    376. 摆动序列 题目: 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如: [1,7,4,9 ...

  2. 【LeetCode】376. 摆动序列(图解)

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

  3. 376. 摆动序列 golang

    376. 摆动序列 求取所有的差值保存起来.然后再判断一正一负的规律是否成立 var flag int func wiggleMaxLength(nums []int) int {if len(num ...

  4. leetcode - 376. 摆动序列

    376. 摆动序列 -------------------------------------------- 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在 ...

  5. 贪心1|455.分发饼干|376. 摆动序列|53. 最大子序和

    贪心1|455.分发饼干|376. 摆动序列|53. 最大子序和 一.455.分发饼干 题目连接:455. 分发饼干 - 力扣(LeetCode) 思路1:用贪心思想,将饼干数组和胃口数组先排序,然后 ...

  6. 【LeetCode每日一题】——376.摆动序列

    文章目录 一[题目类别] 二[题目难度] 三[题目编号] 四[题目描述] 五[题目示例] 六[解题思路] 七[题目提示] 八[题目进阶] 九[时间频度] 十[代码实现] 十一[提交结果] 一[题目类别 ...

  7. 力扣贪心算法专题(一)455.分发饼干 376. 摆动序列 53. 最大子序和 122.买卖股票的最佳时机II 1005.K次取反后最大化的数组和 思路及C++实现 贪心算法 动态规划

    文章目录 贪心算法 455.分发饼干 思路 步骤 代码 376. 摆动序列 贪心算法 思路 分析 代码 动态规划 思路 步骤 代码 53. 最大子序和 暴力解法 双层for循环 贪心算法 思路 分析 ...

  8. leetcode 376. 摆动序列 思考分析

    目录 题目 思路分析 代码 总结 题目 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如, [1 ...

  9. leetcode 376. 摆动序列(dp)

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

最新文章

  1. 并发和并行的区别_多核、多处理器、并发、并行、超线程概念总结
  2. php 回调通知 连连支付_php怎么写连连支付退款
  3. #1181 : 欧拉路·二(无向图的欧拉路)
  4. zen cart 操作-修改
  5. 防抖和节流(白话版)
  6. 36氪首发|一年完成三轮融资,STEAM 教育内容供应商「唯科乐」获 Pre-A 轮融资...
  7. echarts源码打包_Echarts源码阅读指南
  8. ASPack 2.x (without poly) - Alexey Solodovnikov [Overlay]脱壳
  9. GridView固定表头
  10. 拓端tecdat|HAR-RV-J与递归神经网络(RNN)混合模型预测和交易大型股票指数的高频波动率
  11. flash builder 序列号
  12. python 魔兽世界钓鱼_有关魔兽世界怀旧服的钓鱼工具的一点思考
  13. em算法 实例 正态分布_4-EM算法原理及利用EM求解GMM参数过程
  14. Matlab求解线性规划
  15. C#自定义好看的消息提示窗口MessageBox
  16. 【优化系列】汇编优化技术(六):ARM架构64位(AARCH64)汇编优化及demo
  17. 安装MongoDB出现 service MongoDB failed to start,verify that you have sufficient privileges to start
  18. 《Graph Learning》| HIN-基于元路径的相似度
  19. 中文计数法亿兆京垓秭穰沟涧正载
  20. 10g数据库入门与实践 oracle_oracle10g数据库入门与实践

热门文章

  1. android 定位 闪退_Unity3D研究院之全方位定位Android闪退(九十三)
  2. 网络工程师【软考】02
  3. Python小爬虫之协程爬虫快速上手
  4. 学习笔记——深蓝学院点云系列公开课05:3D物体检测的发展与未来
  5. 阿里飞冰(Iceworks)入门和飞冰是干什么的
  6. (48)性能测试——聚合报告
  7. Unity中Combined Mesh (root: scene)的解决方法
  8. 深入理解Spring两大特性:IoC和AOP
  9. html中的字体英文名称
  10. 如何在Excel中创建动态定义的范围