LeetCode-摆动序列

2,319 阅读2分钟

算法记录

LeetCode 题目:

  如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。

  • 例如,[1, 7, 4, 9, 2, 5] 是一个摆动序列,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。

  • 相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。   给你一个整数数组 nums ,返回 nums 中作为 摆动序列最长子序列的长度 。


说明

一、题目

输入: nums = [1,7,4,9,2,5]
输出: 6
解释: 整个序列均为摆动序列,各元素之间的差值为 (6, -3, 5, -7, 3) 。

二、分析

  • 因为是一个求解子序列的问题,如果我们不使用特殊算法来进行优化的话时间复杂度会很高,考虑使用什么算法来简化求解。
  • 首先分析题意,我们可以从第一位一直开始计算,如果当前的数据能够和之前的数据形成峰或者谷的话则进行序列增加。
  • 如果相等的话也就是说和前面一个的序列情况是一致的,只需要正常转移即可。
  • 其中峰或者谷的计算要分两步,一是当前数比前一个数大,也就是需要计算以前一个数作为峰的最大值 +1;当前数比前一个数小的话,也就是需要前一个数作为谷的最大值 +1。
  • 因为从前至后的过程中序列总是呈现增大趋势的,也就是所谓的贪心策略。
class Solution {
    public int wiggleMaxLength(int[] nums) {
        int[][] dp = new int[nums.length][2];
        dp[0][0] = 1;
        dp[0][1] = 1;
        for(int i = 1; i < nums.length; i++) {
            for(int j = i - 1; j >= 0; j--) {
                if(nums[i] - nums[j] > 0) dp[i][0] = Math.max(dp[i][0], dp[j][1] + 1);
                if(nums[i] - nums[j] < 0) dp[i][1] = Math.max(dp[i][1], dp[j][0] + 1);
                if(nums[i] == nums[j]) {
                    dp[i][0] = Math.max(dp[j][0], dp[i][0]);
                    dp[i][1] = Math.max(dp[j][1], dp[i][1]);
                }
            }
        }
        return Math.max(dp[nums.length - 1][0], dp[nums.length - 1][1]);
    }
}

总结

贪心算法。