【leetcode】376. 摆动序列

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

例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的。相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。

给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。

输入: [1,17,5,10,13,15,10,5,16,8]
输出: 7
解释: 这个序列包含几个长度为 7 摆动序列,其中一个可为[1,17,10,13,10,16,8]。

分析

  • 满足题目中的摆动序列有两种,即第一个差值是正数或是负数,找出这两类最长的摆动序列,取其中较大者即为所求解。

  • 以第一个差值为负数的摆动序列为例。用pre来保存已生成的摆动序列的最后一个值,遍历整个数组当发现当前元素可以加入已生成的摆动的序列(即上升时满足该元素大于pre,或下降时小于pre),则加入摆动序列,并更新摆动序列的长度。否则,我们应该用该元素更新pre以增加后面能够加入进该摆动序列的元素的可能性,例如当前的状态是下降的,而目前的pre = 5,若碰到的元素为9,我们应将pre更新为9,因为在后面的元素中找到小于9的比小于5的可能性要大的多。(贪心策略),该算法可以保证最后的序列长度一定是最长的。

  • 这样遍历2次数组后即可找出最长的摆动序列

  • 算法的时间复杂度为O(2n),空间复杂度为O(1)

关键是False和Ture(忘了)! 因为决定了是否是递增or递减序列(递增保留最大,递减保留最小)

还有pre每次保存序列的最后一个值!!!!

class Solution(object):
    def wiggleMaxLength(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        # 在连续递增,递减时,只保留首尾元素
        def wigglelength(type,nums):
            if (len(nums)==0): return 0
            # pre来保存已生成的摆动序列的最后一个值
            pre,cnt = nums[0],1
            for i in range(1,len(nums)):
                if type and pre<nums[i]:
                    cnt+=1
                    type = False
                elif not type and pre>nums[i]:
                    cnt+=1
                    type=True

                pre = nums[i] # 摆动序列的最后一个值

            return cnt

        # 后比前大,遍历一次; 前比后大,遍历一次
        return max(wigglelength(True,nums),wigglelength(False,nums))

 

参考:

Leetcode 376 摆动序列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值