码迷,mamicode.com
首页 > 其他好文 > 详细

376. Wiggle Subsequence

时间:2021-04-10 13:10:26      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:else   记录   去掉   题目   元素   上下   位置   vector   solution   

思路:
首先是子序列,所以说并不一定要求是连续的序列满足摆动序列。同时题目要求的是最长摆动子序列的长度。
动态规划
那么我们可以考虑通过记录摆动的长度得到,什么是摆动的长度呢?我们可以用up和down两个变量来记录摆动的次数,如果前一个差为正数,当前差为负,那么就是遇到了一个down,模拟往下摆动。如果一个差为负数,当前差为正,那就是遇到一个up,向上摆动。所以我们对上下摆动的定义是,原来是向下摆动才会出现向上摆动,如果原来时负数差,现在还有一个负数差,就不能算时向下摆动。
那么我们从i=1的位置开始遍历,首先判断 nums[i]和nums[i-1]的关系,如果是大于说明是向上摆动一次,那么up = down+1,如果上一个差也是正数,这次也是整数,那么向上摆动的次数是不会被影响的,只有down变了才会影响向上摆动的次数。同样如果nums[i]小于nums[i-1]那么就是向下摆动一次,就是 down=up+1,理由同上。那么最后我们就去 down和up的最大值,这就是我们要的最长子序列长度。
只有down-up或者up-down才会计数一次,down-down和up-up都不会计数。
例如:

nums  1,3,  2, 5 , 5,4
up    1,1+1,2,3+1,3+1,4
down  1,1, 1+2,3,  3,4+1=5

那么最后最长子序列的长度就是5.

代码:

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int n=nums.size();
        int up=1,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);
    }
};

另一种贪心算法。即使中间出现不满足摆动序列的数字串,但后面仍会发现和前面最后一个满足摆动序列数字配对的数字,那么我们每次只需要找满足摆动序列的数字即可。这里需要用一个diff_pre来记录前一个是up还是down以便于寻找后面的数字用来做down还是up。
代码:

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int n=nums.size();
        if(n<2) return n;
        int res=0;
        int diff_pre=nums[1]-nums[0],diff=0;
        res=(diff_pre!=0?2:1);
        for(int i=2;i<n;++i){
            diff=nums[i]-nums[i-1];
            if((diff>0&&diff_pre<=0)||(diff<0&&diff_pre>=0)){  //用等于是因为存在重复元素,如果去掉等于,那么在如2,3,3,3,4,当i指向4时就无法进入if了。
                res++;
                diff_pre=diff;
            }
        }
        return res;
    }
};

376. Wiggle Subsequence

标签:else   记录   去掉   题目   元素   上下   位置   vector   solution   

原文地址:https://www.cnblogs.com/Mrsdwang/p/14638683.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!