Wiggle Subsequence

题目来源

输入一个整型数组nums,该数组表示一个序列,序列中元素的大小顺序是随机的。从数组中去除若干个元素后,可以得到wiggle sequence。求能够得到的最长wiggle sequence的长度。
wiggle sequence是一种满足相邻元素的差值严格遵循正负交替特点的序列。长度为1的序列都算作wiggle sequence。
例如:
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

---------------------------
题目要求时间复杂度为O(n),可以考虑用空间换时间——采用DP(动态规划)的思想来解决这个问题。
(1)首先考虑一般情况
创建两个辅助数组lengths和diffs,其元素分别用于记录序列从最左边到当前位置为止,所能得到的最长wiggle sequence的长度和当前元素在wiggle sequence中相对于前一个元素的差值。
在已知lengths[k] 和diffs[k]的情况下,可以用下面的方法将lengths和diffs推进到k+1:
首先求出序列中第k+1个元素与第k个元素的差值,即diff = nums[k + 1] – nums[k]。根据diff的不同进行不同的处理:
1)diff = 0,说明这两个元素相等,此时lengths[k + 1] = lengths[k],diffs[k + 1] = diffs[k];
2)diff与diffs[k]同为正数或同为负数,说明这两个元素中需要去除一个,因此到k+1位置为止的最长wiggle subsequence长度与k的相同,此时lengths[k + 1] = lengths[k],diffs[k + 1] = diff;
2)diff与diffs[k]不同号,说明可以在k的最长wiggle subseequence的基础上追加一个元素nums[k + 1]。此时lengths[k + 1] = lengths[k] + 1,diffs[k + 1] = diff。
(2)空间复杂度的优化
事实上,对于上述两个辅助数组lengths和diffs,每次迭代时都只用到了最近的一个元素。因此,可以将这两个数组简化为两个变量——maxlen和diff。
(3)考虑边界条件
上述算法从序列的第2个元素开始处理,直到序列的最后一个元素,最后得到的lengths的最后一个元素即为整个序列的最长wiggle subsequence的长度。
如果输入序列含有0元素,那么直接返回0。另外,diff的初始值没有意义,因此需要在迭代时进行判断。

实现代码如下:

class Solution {
    public int wiggleMaxLength(int[] nums) {
        if(nums.length == 0) {
            return 0;
        }
        
        int maxlen = 1, diff = 0;
        for(int i = 1; i < nums.length; i++) {
            int newDiff = nums[i] - nums[i - 1];
            if(newDiff != 0 && (diff == 0 || newDiff * diff < 0)) {
                diff = newDiff;
                maxlen++;
            }
        }
        
        return maxlen;
    }
}
算法只需要进行一轮迭代并且只用到了有限个状态变量,因此时间复杂度为O(n),空间复杂度为O(1)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值