标签: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;
}
};
标签:else 记录 去掉 题目 元素 上下 位置 vector solution
原文地址:https://www.cnblogs.com/Mrsdwang/p/14638683.html