376. Wiggle Subsequence(摆动子序列)
题目链接
https://leetcode.com/problems/wiggle-subsequence/description/
题目描述
A sequence of numbers is called a wiggle sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a wiggle sequence.
For example,
[1,7,4,9,2,5]
is a wiggle sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast,[1,4,7,2,5]
and[1,7,4,5,5]
are not wiggle sequences, the first because its first two differences are positive and the second because its last difference is zero.Given a sequence of integers, return the length of the longest subsequence that is a wiggle sequence. A subsequence is obtained by deleting some number of elements (eventually, also zero) from the original sequence, leaving the remaining elements in their original order.
Examples:
Input:
[1,7,4,9,2,5]
Output:6
The entire sequence is a wiggle sequence.Input:
[1,17,5,10,13,15,10,5,16,8]
Output:7
There are several subsequences that achieve this length. One is[1,17,10,13,10,16,8]
.Input:
[1,2,3,4,5,6,7,8,9]
Output:2
题目分析
这道题目和最长递增子序列有很大程度的相似,所以可以借鉴最长递增子序列的算法。在每一次摆动中,我们以增长为例(降低是同样的道理):
如果当前元素比前一个元素大,那么即实现了增长;而如果比前一个元素还要小,就可以替换掉前一个元素,这样一来可以留下更大的增长空间。
方法:贪心
算法描述
初始化两个队列,两个队列中只放入nums[0]
元素。(一个队列代表由增长开始,另一个代表由降低开始),遍历nums
,对于两个队列:
1. 若此轮是增长:nums[i]
大于队尾元素,则nums[i]
入队;nums[i]
小于队尾元素,则用nums[i]
替换队尾元素
2. 若此轮是降低:nums[i]
小于队尾元素,则nums[i]
入队;nums[i]
大于队尾元素,则用nums[i]
替换队尾元素
参考代码
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if (nums.empty())
return 0;
vector<int> increase, decrease;
increase.push_back(nums[0]);
decrease.push_back(nums[0]);
for (int i = 1; i < nums.size(); i++) {
if (increase.size() % 2 == 0) {
if (nums[i] > increase[increase.size() - 1])
increase[increase.size() - 1] = nums[i];
if (nums[i] < increase[increase.size() - 1])
increase.push_back(nums[i]);
}
else {
if (nums[i] < increase[increase.size() - 1])
increase[increase.size() - 1] = nums[i];
if (nums[i] > increase[increase.size() - 1])
increase.push_back(nums[i]);
}
if (decrease.size() % 2 == 0) {
if (nums[i] < decrease[decrease.size() - 1])
decrease[decrease.size() - 1] = nums[i];
if (nums[i] > decrease[decrease.size() - 1])
decrease.push_back(nums[i]);
}
else {
if (nums[i] > decrease[decrease.size() - 1])
decrease[decrease.size() - 1] = nums[i];
if (nums[i] < decrease[decrease.size() - 1])
decrease.push_back(nums[i]);
}
}
return increase.size() > decrease.size() ? increase.size() : decrease.size();
}
};