求最长摆动子序列。
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
这个题很有意思,有很多种解法,用来练练dp...然而还是看题解才会的 = =
一个普通dp代码:
#include "stdafx.h" #include <iostream> #include <vector> #include <minmax.h> using namespace std; class Solution { public: int wiggleMaxLength(vector<int>& nums) { if (nums.empty()) return {}; if (nums.size() < 2) return nums.size(); vector<int> up(nums.size()); vector<int> down(nums.size()); for (int i = 1; i < nums.size(); i++) for (int j = 0; j < i; j++) { if (nums[i] > nums[j]) up[i] = max(up[i], down[j] + 1); else if (nums[i] < nums[j]) down[i] = max(down[i], up[j] + 1); } return 1 + max(up[nums.size() - 1], down[nums.size() - 1]); } }; int main() { vector<int> nums{ 1,17,5,10,13,15,10,5,16,8 }; cout << Solution().wiggleMaxLength(nums) << endl; getchar(); return 0; }
运行结果:
7
时间复杂度O(n^2),空间复杂度O(n)。
重点是这个优化的dp算法,时间复杂度O(n),空间复杂度O(1):
#include "stdafx.h" #include <iostream> #include <vector> #include <minmax.h> using namespace std; class Solution { public: int wiggleMaxLength(vector<int>& nums) { if (nums.empty()) return {}; if (nums.size() < 2) return nums.size(); 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); } }; int main() { vector<int> nums{ 1,17,5,10,13,15,10,5,16,8 }; cout << Solution().wiggleMaxLength(nums) << endl; getchar(); return 0; }
运行结果:
7
这个算法实在又简洁又易懂。