LeedCode 376. 摆动序列
一、题目
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。例如, [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. 摆动序列相关推荐
- LeetCode 376. 摆动序列 中等难度
376. 摆动序列 题目: 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如: [1,7,4,9 ...
- 【LeetCode】376. 摆动序列(图解)
376. 摆动序列 一.问题 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如, [1,7,4, ...
- 376. 摆动序列 golang
376. 摆动序列 求取所有的差值保存起来.然后再判断一正一负的规律是否成立 var flag int func wiggleMaxLength(nums []int) int {if len(num ...
- leetcode - 376. 摆动序列
376. 摆动序列 -------------------------------------------- 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在 ...
- 贪心1|455.分发饼干|376. 摆动序列|53. 最大子序和
贪心1|455.分发饼干|376. 摆动序列|53. 最大子序和 一.455.分发饼干 题目连接:455. 分发饼干 - 力扣(LeetCode) 思路1:用贪心思想,将饼干数组和胃口数组先排序,然后 ...
- 【LeetCode每日一题】——376.摆动序列
文章目录 一[题目类别] 二[题目难度] 三[题目编号] 四[题目描述] 五[题目示例] 六[解题思路] 七[题目提示] 八[题目进阶] 九[时间频度] 十[代码实现] 十一[提交结果] 一[题目类别 ...
- 力扣贪心算法专题(一)455.分发饼干 376. 摆动序列 53. 最大子序和 122.买卖股票的最佳时机II 1005.K次取反后最大化的数组和 思路及C++实现 贪心算法 动态规划
文章目录 贪心算法 455.分发饼干 思路 步骤 代码 376. 摆动序列 贪心算法 思路 分析 代码 动态规划 思路 步骤 代码 53. 最大子序和 暴力解法 双层for循环 贪心算法 思路 分析 ...
- leetcode 376. 摆动序列 思考分析
目录 题目 思路分析 代码 总结 题目 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如, [1 ...
- leetcode 376. 摆动序列(dp)
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如, [1,7,4,9,2,5] 是一个摆动序列, ...
最新文章
- 并发和并行的区别_多核、多处理器、并发、并行、超线程概念总结
- php 回调通知 连连支付_php怎么写连连支付退款
- #1181 : 欧拉路·二(无向图的欧拉路)
- zen cart 操作-修改
- 防抖和节流(白话版)
- 36氪首发|一年完成三轮融资,STEAM 教育内容供应商「唯科乐」获 Pre-A 轮融资...
- echarts源码打包_Echarts源码阅读指南
- ASPack 2.x (without poly) - Alexey Solodovnikov [Overlay]脱壳
- GridView固定表头
- 拓端tecdat|HAR-RV-J与递归神经网络(RNN)混合模型预测和交易大型股票指数的高频波动率
- flash builder 序列号
- python 魔兽世界钓鱼_有关魔兽世界怀旧服的钓鱼工具的一点思考
- em算法 实例 正态分布_4-EM算法原理及利用EM求解GMM参数过程
- Matlab求解线性规划
- C#自定义好看的消息提示窗口MessageBox
- 【优化系列】汇编优化技术(六):ARM架构64位(AARCH64)汇编优化及demo
- 安装MongoDB出现 service MongoDB failed to start,verify that you have sufficient privileges to start
- 《Graph Learning》| HIN-基于元路径的相似度
- 中文计数法亿兆京垓秭穰沟涧正载
- 10g数据库入门与实践 oracle_oracle10g数据库入门与实践