[Leetcode学习-c++&java]Wiggle Subsequence(震荡序列)

46 篇文章 0 订阅

问题:

难度: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;
	}
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值