376. Wiggle Subsequence

本文介绍了最长摆动序列的线性解法,定义了up[i]和down[i]分别表示从0到i组成的最长摆动序列,且最后两个元素差为正和负的情况。给出状态转移方程,并对不同情况进行分析,时间复杂度为O(n),空间复杂度可优化到O(1)。

线性解法:

定义up[i]表示从0到i组成最长的wiggle序列,并且序列的最后两个元素a,b的差是正的,即a<b;

同理down[i]表示从0到i组成的最长wiggle序列,并且序列最后的两个元素a和b的差是负的,即a>b;

状态转移方程:

up[i] =   down[i-1]+1 (nums[i]>nums[i-1])

             up[i-1] (nums[i] <= nums[i-1])

 

down[i] = up[i-1]+1 (nums[i]<nums[i-1])

               down[i-1] (nums[i] >= nums[i-1])

分析如下:

当nums[i]>nums[i-1]:

    Sdown[i-1]表示0到i-1组成的最长wiggle序列,最后一组差值为负,设最后一个元素为N

    如果Sdown[i-1]包含nums[i-1], 那么自然up[i] = down[i-1]+1;

    如果Sdown[i-1]不包含nums[i-1]:

          1. N<nums[i-1], 由nums[i-1]<nums[i],得N<nums[i],也是成立的;

          2. 如果N>nums[i-1],那么用nums[i-1]替换N,得到新的Sdown[i-1]序列,依然是最后一个递减的,长度也是最长的,也是成立的;

对于nums[i]==nums[i-1],得到的结果和nums[i-1]得到的结果是一样的;

对于nums[i] < nums[i-1]:

     假设存在Sdown[i-1]的序列可以加上nums[i]得到更长的序列,设Sdown[i-1]最后一个元素是N,则N<nums[i];

     因为nums[i]<nums[i-1], 所以N<nums[i-1],这意味着,如果存在使用nums[i-1]得到更长的序列,这个序列在计算up[i-1]的时候已经更新到了,所以up[i] = up[i-1];

 down[i]原理以此类似,这里不展开了。

时间负载度O(n),注意到这里计算up[i]和down[i],只需要用到up[i-1]和down[i-1],所以空间复杂度可以优化到O(1)。

代码如下:

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int n = nums.size();
        if(n==0) return 0;
        int up = 1, down = 1;
        for(int i = 1; i<nums.size(); i++){
            if(nums[i]>nums[i-1]){
                up = down+1;
            } else if(nums[i]<nums[i-1]){
                down = up+1;
            }
        }
        return max(up, down);
    }
};

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值