如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。
例如, [1,7,4,9,2,5]
是一个摆动序列,因为差值 (6,-3,5,-7,3)
是正负交替出现的。相反, [1,4,7,2,5]
和 [1,7,4,5,5]
不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。
示例 1:
输入: [1,7,4,9,2,5] 输出: 6 解释: 整个序列均为摆动序列。
示例 2:
输入: [1,17,5,10,13,15,10,5,16,8] 输出: 7 解释: 这个序列包含几个长度为 7 摆动序列,其中一个可为[1,17,10,13,10,16,8]。
示例 3:
输入: [1,2,3,4,5,6,7,8,9] 输出: 2
进阶:
你能否用 O(n) 时间复杂度完成此题?
解题思路:
动态规划。假设dp[n]为前n个数中找到的最长摆动序列,长度为len,摆动序列最后是状态sgn,sgn=true说明下一个点需要上升,sgn=false说明下一个点需要下降,摆动序列最后的数字为data。对于第n+1个数而言,它对之前的最长序列存在4中影响,如下:
- sgn=true,nums[n+1]>data,len++;
- sgn=true,nums[n+1]<=data, data=nums[n+1]。
- sgn=false,nums[n+1]<data, len++;
- sgn=false,nums[n+1]>=data, data=nums[n+1]。
本题需要注意的是,摆动序列最开始可能上升或者下降,需要先获取第一个摆动状态。如果没有搜索到摆动状态,return 1.
class Solution { public: int wiggleMaxLength(vector<int>& nums) { int size = nums.size(); if (size <= 1) return size; int len = 1; //查找第一个是上升还是下降 int find = false; bool sgn = true;//需要一个上升端,false为下降端 for (int j = 1; j <= size - 1; j++) { if (nums[j - 1] < nums[j]) sgn = true; if (nums[j - 1] > nums[j]) sgn = false; if (nums[j - 1] != nums[j]) { find = true; break; } } if (find == false) return 1; int data = nums[0]; for (int i = 2; i <= size; i++) { if (sgn == true) { if (nums[i - 1]>data) { len++; data = nums[i - 1]; sgn = false; } else { data = nums[i - 1]; } } else { if (nums[i - 1] < data) { len++; data = nums[i - 1]; sgn = true; } else { data = nums[i - 1]; } } } return len; } }; |