原文:https://leetcode-cn.com/problems/wiggle-subsequence/solution/bai-dong-xu-lie-by-leetcode/
给定一个整数序列,返回作为摆动序列的最长子序列的长度,通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序
这个删除是指删除上升后又接着上升的元素
1、暴力:超时
2、动态规划:
up[i]
是目前为止最长的以第i
个元素结尾上升的摆动序列的长度。
down[i]
是目前为止最长的以第i
个元素结尾下降的摆动序列的长度。
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int n = nums.size();
if(n < 2)
{
return n;
}
vector<int>up(n, 0);
vector<int>down(n, 0);
for(int i = 1; i < n; i++)
{
for(int j = 0; j < i; j++)
{
if(nums[j] < nums[i])
{
up[i] = max(up[i], down[j] + 1);
}
else if(nums[j] > nums[i])
{
down[i] = max(down[i], up[j] + 1);
}
}
}
return 1 + max(down[n-1], up[n-1]);
//up[i] >= down[i-1]; down[i] > up[i-1]; +1是第一个没算
}
};
3、线性动态规划:
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int n = nums.size();
if(n < 2)
{
return n;
}
vector<int>up(n, 0);
vector<int>down(n, 0);
up[0] = down[0] = 1;
for(int i = 1; i < n; i++)
{
if(nums[i] > nums[i-1])
{
up[i] = down[i-1] + 1;
down[i] = down[i-1];
}
else if(nums[i] < nums[i-1])
{
down[i] = up[i-1] + 1;
up[i] = up[i-1];
}
else
{
up[i] = up[i-1];
down[i] = down[i-1];
}
}
return max(down[n-1], up[n-1]);
}
};
4、空间优化:
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int n = nums.size();
if(n < 2)
{
return n;
}
int up = 1;
int 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);
}
};
5、贪心
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int n = nums.size();
if(n < 2) return n;
int prediff = nums[1] - nums[0];
int count = prediff == 0 ? 1 : 2;
for(int i = 2; i < n; i++)
{
int diff = nums[i] - nums[i-1];
if((diff > 0 && prediff <= 0) || (diff < 0 && prediff >= 0))
{//prediff == 0只在开始出现
count++;
prediff = diff;
}
}
return count;
}
};