题目
解决方法
这道题目与之前做过的最长上升子序列很类似,我在这篇博客中也写到过。
动态规划
方法与最长上升子序列类似,不过需要注意对序列摆动方向进行判断。
代码实现:
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if (nums.size() < 2) {
return nums.size();
}
if (nums.size() == 2) {
if (nums[0] == nums[1])
return 1;
return nums.size();
}
#define UP 1 // 该元素相比之前的元素是上摆
#define DOWN 0 // 下摆
#define NO 2 // 无摆动,即与之前的所有元素相等
int direct;
vector<vector<int>> dp(nums.size(), vector<int>(2, 0));
// 使用一个二维数组来存放信息,每个元素又包含了数组对应位置的元素及之前元素中的最长摆动序列长度与摆动方向信息
dp[0][0] = 1;
dp[0][1] = NO;
if (nums[0] == nums[1]){ // 为前dp数组的前两个元素赋值
dp[1][0] = 1;
dp[1][1] = NO;
} else{
nums[0] > nums[1] ? dp[1][1] = DOWN : dp[1][1] = UP;
dp[1][0] = 2;
}
for (int i = 2; i < nums.size(); i++) {
for (int j = 0; j < i; j++) {
if (nums[i] == nums[j]) // 相等则不做操作
continue;
if (dp[j][1] == UP) { // 若为上摆,则nums[i]必须比nums[j]小才可能组成摆动序列
if (nums[i] < nums[j]){
if (dp[i][0] < dp[j][0] + 1) {
dp[i][0] = dp[j][0] + 1;
dp[i][1] = DOWN;
}
continue;
}
} else if (dp[j][1] == DOWN) { // 若为下摆,...
if (nums[i] > nums[j]) {
if (dp[i][0] < dp[j][0] + 1) {
dp[i][0] = dp[j][0] + 1;
dp[i][1] = UP;
}
continue;
}
} else { // 若无摆动, ...
if (nums[i] > nums[j]) {
if (dp[i][0] < dp[j][0] + 1) {
dp[i][0] = dp[j][0] + 1;
dp[i][1] = UP;
}
} else {
if (dp[i][0] < dp[j][0] + 1) {
dp[i][0] = dp[j][0] + 1;
dp[i][1] = DOWN;
}
}
}
}
}
int max = dp[0][0];
for (int i = 1; i < nums.size(); i++) {
if (dp[i][0] > max){ // 取出最长摆动序列长度
max = dp[i][0];
}
}
return max;
}
};
时间复杂度为(O(n^2)),还有很大的优化空间,不过今天没有时间继续研究了,留作下次再看:力扣官方解答。