问题:
难度:medium
说明:
题目给出一个数组,然后找到按数组顺序的子序列,要求子序列是震荡的,震荡的意义是子序列后一个元素对相邻前一个元素之间的差值是正负相间:
1 2 1 2 这样的数组就是震荡的,因为差值是 1 -1 1
2 6 1 8 也是 两两差值是 4 -5 7。
此外注意是子序列,不是子串(数组内连续的子序列)
题目连接:https://leetcode.com/problems/wiggle-subsequence/
输入案例:
Example 1:
Input: nums = [1,7,4,9,2,5]
Output: 6
Explanation: The entire sequence is a wiggle sequence.
Example 2:
Input: nums = [1,17,5,10,13,15,10,5,16,8]
Output: 7
Explanation: There are several subsequences that achieve this length. One is [1,17,10,13,10,16,8].
Example 3:
Input: nums = [1,2,3,4,5,6,7,8,9]
Output: 2
我的代码:
数组内每个元素都要两个方面:1、当前元素差值是正,那么就要找到当前元素前面的元素最长的一条差值为负子序列。2、差值为负就反过来
创建一个二维数组记录每个元素差值正负的最长子序列即可。
其实是一道 DP 的题目。
Java:
class Solution {
public int wiggleMaxLength(int[] nums) {
int len = nums.length, max = 1;
int[][] preArr = new int[len][2]; // 0 上升 1 下降
preArr[0][0] = preArr[0][1] = 1;
for(int i = 1; i < len; i ++) {
int j = i - 1;
while(j >= 0 && nums[i] - nums[j] > 0) {
preArr[i][0] = Math.max(preArr[i][0], preArr[j][1] + 1);
j --;
}
j = i - 1;
while(j >= 0 && nums[i] - nums[j] < 0) {
preArr[i][1] = Math.max(preArr[i][1], preArr[j][0] + 1);
j --;
}
max = Math.max(Math.max(preArr[i][0], preArr[i][1]), max);
}
return max;
}
}
C++:
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int len = nums.size(), maxVal = 1;
int **preArr = new int*[nums.size()];
for (int i = 0; i < len; i++) preArr[i] = new int[2];
preArr[0][0] = preArr[0][1] = 1;
for (int i = 1; i < len; i++) {
int j = i - 1;
while (j >= 0) {
if (nums[i] - nums[j] > 0) preArr[i][0] = max(preArr[i][0], preArr[j][1] + 1);
j--;
}
j = i - 1;
while (j >= 0) {
if (nums[i] - nums[j] < 0) preArr[i][1] = max(preArr[i][1], preArr[j][0] + 1);
j--;
}
maxVal = max(max(preArr[i][0], preArr[i][1]), maxVal);
}
return maxVal;
}
};