376. 摆动序列
时间:2020年12月14日
知识点:贪心、动态规划
题目链接:https://leetcode-cn.com/problems/wiggle-subsequence/
题目
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。
例如, [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) 时间复杂度完成此题?
解法:
贪心
- 我这里先想到的是贪心 自己先模拟一遍
- 我们对于摆动顺序 如果是上升序列 我们要找之后是上升的中最大的数 为后面添加更多的可能性
- 对于下降也是 我们找下降的最小那个 可以用while去找
- 只需要遍历一次数组 记录上一个是什么 如果当前比上一个小 说明处于下降 找最小的那个 更新
- 上升的时候也同理 注意相等的情况 也要继续往后找
动态规划
- 动态规划的角度去找
- 定义两个数组 一个用来标记最后两个数字递增的最长摆动序列长度 as up 一个标记最后两个数字递减的最长摆动序列长度 as down
- 比如 1 3 2 4 是一个上升摆动序列 1 3 4 2是一个下降摆动序列
- 最终要的是如何更新这两个摆动序列呢
- 我们希望的是遍历一遍就可以得到答案 我们需要和上一个数字做对比
- 如果 上一个数字 >= 当前数字 如 1 17 5 和 1 17 5 4
- 上升序列 = 上一个上升序列的结果 如 1 17 5
- 下降序列 = max(上一个上升结果+1 也就新的结果 , 上一个下降结果) 如 1 17 5 4
- 如果 上一个数字 < 当前数字 如 1 17 4 5和 1 17 18
- 上升序列 = max(上一个下降结果+1 , 上一个上升结果) 如 1 17 4 5
- 下降序列 = 上一个下降序列 如 1 17 18
实例2 [1,17,5,10,13,15,10,5,16,8]
up 1 2 2 4 4 4 4 4 6 6
down 1 1 3 3 3 3 5 5 5 7
- 注意状态压缩
- 最大上升序列个数 和 最大下降个数 绝对值不超过1 不可能两个连续增加
代码
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
/*
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if(nums.size() == 0)
return 0;
int pre = nums[0],ans = 1;
int i = 1;
while(i < nums.size()){
if(pre < nums[i]){
while(i < nums.size() && pre <= nums[i]){
pre = nums[i];
i++;
}
ans++;
}
else if(pre > nums[i]){
while(i < nums.size() && pre >= nums[i]){
pre = nums[i];
i++;
}
ans++;
}
else
i++;
}
return ans;
}
};*/
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int n = nums.size();
if (n < 2) {
return n;
}
int up = 1, down = 1;
for (int i = 1; i < n; i++){
if (nums[i] > nums[i - 1]){
up = max(up, down + 1);// up = down + 1;
} else if (nums[i] < nums[i - 1]){
down = max(up + 1, down); //down = up + 1;
}
}
return max(up, down);
}
};
int main()
{
vector<int> nums{1,17,5,10,13,15,10,5,16,8};
Solution s;
cout<<s.wiggleMaxLength(nums)<<endl;
return 0;
}
今天也是爱zz的一天哦!