一、题目描述
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。
第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。
例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的。
相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,
第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
给定一个整数序列,返回作为摆动序列的最长子序列的长度。
通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。
输入: [1,7,4,9,2,5]
输出: 6
解释: 整个序列均为摆动序列。
二、题解
方法一:dp
- 定义状态:
-
dp[i] 表示 nums 位置 i 的最长摆动序列的长度。
- 思考状态转移方程:
- 如果数字之间的差是异号,即
diff[i] × diff[i-1] < 0
,
dp[i]=dp[i−1]+1,表示最长摆动序列的长度加1。
- 思考初始化:
-
dp[0...len]=2 表示数组至少有两个不重复的数可以组成摆动序列。
- 思考输出:
dp[len]
public int wiggleMaxLength(int[] nums) {
int N = nums.length;
if (N <= 1) return N;
int[] diff = new int[N];
int len = 0;
for(int i = 1; i < N; i++) {
if (nums[i] != nums[i-1])
diff[len++] = nums[i] - nums[i-1];
}
if (len == 0) return 1;
int[] dp = new int[len + 1];
Arrays.fill(dp, 2);
for (int i = 1; i <= len; i++) {
if (diff[i] * diff[i-1] < 0)
dp[i] = dp[i-1] + 1;
else
dp[i] = dp[i-1];
}
return dp[len];
}
复杂度分析
- 时间复杂度:
O(N),
- 空间复杂度:
O(N),
方法二:状态机
复杂度分析
- 时间复杂度:
O(),
- 空间复杂度:
O(),