首页 > 编程语言 >吴师兄学算法day08 贪心 376. 摆动序列

吴师兄学算法day08 贪心 376. 摆动序列

时间:2024-01-20 19:56:10浏览次数:39  
标签:day08 nums 元素 len length 序列 new 376 贪心

题目:376. 摆动序列

难点:

  • 理解难。思路不好想
  • 看了卡尔的思路。
  • 可以先去重,再遍历。

我的代码加调试:

from typing import List


# 摆动序列
class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:

        if len(nums) == 1:
            return 1
        # 1.先去重把
        new_nums = []
        for i in range(len(nums)):
            if i == 0 or nums[i] != nums[i - 1]:  # 只要不等于前1个,就添加进来 第一个无论怎样都要加进来
                new_nums.append(nums[i])
        # print(new_nums)
        if len(new_nums) == 1: return 1  # 例如 [2,2,2,2]

        if len(new_nums) == 2: return 2  # 例如 [3,2,2,2,2]
        # 2.现在至少有3个元素了
        # 判断前一个后一个的正负
        res = 2  # 默认包含最两边的
        for i in range(1, len(new_nums) - 1):  # 不算两边的 简化判断
            # 这里注意要每次用后面减去前面的
            # print(f"现在遍历的元素是{nums[i]},前结果{new_nums[i] - new_nums[i - 1]},后结果{new_nums[i+1] - new_nums[i]}")
            if (new_nums[i] - new_nums[i - 1]) * (new_nums[i+1] - new_nums[i]) < 0:  # 一正一负
                # print("===")
                res += 1
        return res


if __name__ == '__main__':
    obj = Solution()
    # obj.wiggleMaxLength([3, 2, 2, 2, 2, 2, 2, 2]) # 1.去重测试
    res = obj.wiggleMaxLength([3, 2, 3, 2, 2, 2, 2, 2]) # 2.测试
    print("结果:",res)

老师的思路:

记录上升状态和下降状态。

老师的代码:


# https://www.algomooc.com
# 作者:程序员吴师兄
# 代码有看不懂的地方一定要私聊咨询吴师兄呀
# 摆动序列(376):https://leetcode-cn.com/problems/wiggle-subsequence/
class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        # 每个元素都有三种状态

        # 1、每个元素的初始状态
        beginState = 0

        # 2、如果当前元素的值大于它之前元素的值
        # 比如 nums[i] > nums[i-1]
        # 那么说明当前元素处于上升阶段,状态设置为 up
        upState = 1


        # 3、如果当前元素的值小于它之前元素的值
        # 比如 nums[i] < nums[i-1]
        # 那么说明当前元素处于下降阶段,状态设置为 down
        downState = 2

        # 如果 nums 长度小于 2 
        if len(nums) < 2 :
            # 由于仅有一个元素或者含两个不等元素的序列也视作摆动序列
            # 直接返回数组的长度
            return len(nums)
        

        # 以第一个元素作为初始的摇摆序列,此时,长度为 1
        length = 1

        # 一开始,状态为 begin
        state = beginState

        # 接下来,开始遍历 nums 中的所有元素
        for i in range(1 ,len(nums)) :
            # 每个元素都有三种状态,在这三种状态下去判断这个元素应该怎么操作

            # 1、如果是在 begin 状态
            if state == beginState :
                # 那么比较 nums[i] 和  nums[i-1] 的大小

                # 此时的元素值为 nums[i],它前面的元素值为 nums[i-1]
                # 如果 nums[i] > nums[i-1],代表着现在处于上升过程
                if nums[i] > nums[i-1] :
                    # 状态修改为 up
                    state = upState
                    # 摆动序列中增加了 nums[i] 这个元素,所以 length 需要加 1
                    length += 1

                # 此时的元素值为 nums[i],它前面的元素值为 nums[i-1]
                # 如果 nums[i] < nums[i-1],代表着现在处于下降过程
                elif nums[i] < nums[i-1] :
                    # 状态修改为 down
                    state = downState
                    # 摆动序列中增加了 nums[i] 这个元素,所以 length 需要加 1
                    length += 1

            # 2、如果是在 up 状态
            # 说明 nums[i] 的前面两个元素 nums[i-2] < nums[i-1],正在处于上升过程
            elif state == upState :

                # 只有此时 nums[i] < nums[i-1]
                # 那么 nums[i-2],nums[i-1],nums[i] 这三者形成一个波峰  ^
                if nums[i] < nums[i-1] :
                    
                    # 此时,由于 nums[i] < nums[i-1],开始处于下降状态了
                    # 状态修改为 down
                    state = downState
                    # 摆动序列中增加了 nums[i] 这个元素,所以 length 需要加 1
                    length += 1
            # 3、如果是在 up 状态
            # 说明 nums[i] 的前面两个元素 nums[i-2] > nums[i-1],正在处于下降过程
            elif state == downState :

                # 只有此时 nums[i] > nums[i-1]
                # 那么 nums[i-2],nums[i-1],nums[i] 这三者形成一个波谷 V
                if nums[i] > nums[i-1] :

                    # 此时,由于 nums[i] > nums[i-1],开始处于上升状态了
                    # 状态修改为 up                    
                    state = upState
                    # 摆动序列中增加了 nums[i] 这个元素,所以 length 需要加 1
                    length += 1

        # 返回结果 length
        # 不需要返回具体序列
        return length

卡尔的写法:

class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        if len(nums) <= 1:
            return len(nums)  # 如果数组长度为0或1,则返回数组长度
        preDiff,curDiff ,result  = 0,0,1  #题目里nums长度大于等于1,当长度为1时,其实到不了for循环里去,所以不用考虑nums长度
        for i in range(len(nums) - 1):
            curDiff = nums[i + 1] - nums[i]
            if curDiff * preDiff <= 0 and curDiff !=0:  #差值为0时,不算摆动
                result += 1
                preDiff = curDiff  #如果当前差值和上一个差值为一正一负时,才需要用当前差值替代上一个差值
        return result

总结:

  • 感觉卡尔的代码更简洁。目前先过掉这题。
  • 下次再来一遍的时候,可以在研究

参考:

卡尔 :https://programmercarl.com/0376.%E6%91%86%E5%8A%A8%E5%BA%8F%E5%88%97.html

 

标签:day08,nums,元素,len,length,序列,new,376,贪心
From: https://www.cnblogs.com/liqi175/p/17977045

相关文章

  • 贪心算法练习
    问题描述:设有n个正整数,将他们连接成一排,组成一个最大的多位整数。例如:n=4时,4个整数21,8,901,6连成的最大整数为:9018621。贪心选择策略:(1)将所有数字转化为字符串形式。(2)将所有字符串按照长度从大到小排序。如果长度相同,则按照字典序从大到小排序。(3)将排序后的字符......
  • 吴师兄学算法day08 贪心 605. 种花问题
    题目:605.种花问题易错点:没想出来,借鉴了灵山的代码的思路,强行种花。我喜欢这个思路。感觉有点像设置哨兵那样的。 我的代码:classSolution:defcanPlaceFlowers(self,flowerbed:List[int],n:int)->bool:#修改数组,每次都种花,#凑够3个0......
  • 吴师兄学算法day08 贪心 860. 柠檬水找零
    题目:860.柠檬水找零易错点:我写的是ifesle哈哈,第一次还写错了。i==20的时候,5元只找了1张。哈哈哈.应该找3张 我的代码:classSolution:deflemonadeChange(self,bills:List[int])->bool:dic={5:0,10:0,20:0}foriinbills:......
  • Contest3376 - 2024寒假集训-排位赛竞赛(一)
    A:幂位和高精度。用高精度加法或乘法算出\(2^{1000}\),再将各位累加即为答案。#include<bits/stdc++.h>usingnamespacestd;#definecctieios::sync_with_stdio(0);cin.tie(0);cout.tie(0)stringAP_add(stringA,stringB)//高精度加法{intlena=A.size()......
  • 吴师兄学算法day08 贪心 134. 加油站
    题目:134.加油站理解难点:理解比较难,就是遍历1遍,尽可能找局部满足要求的。如果总油耗满足要求。那局部油耗找的出发点就是对的。遍历的时候,因为答案唯一,要么就满足要求,要么不满足要求。而<0证明之前的都不满足要求,满足要求的一定在后面。这题还是个环,环这里有点没太理解。环......
  • 吴师兄学算法day08 贪心 LC455. 分发饼干
    题目:455. 分发饼干易错点:这两个变量名容易弄混s是饼干g是胃口图示:我的代码:classSolution:deffindContentChildren(self,g:List[int],s:List[int])->int:#对饼干s排序s.sort()#对孩子们的胃口g进行排序g.sort()......
  • 贪心算法题目2-力扣860
    在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。注意,一开始你手头没有任......
  • 贪心算法-题目3力扣53
    给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组 是数组中的一个连续部分。输入:nums=[-2,1,-3,4,-1,2,1,-5,4]输出:6解释:连续子数组 [4,-1,2,1]的和最大,为 6。子数组 是数组中的一个连续部分。解题思路:从投......
  • 贪心算法-题目1力扣455(简单题)
    力扣455,给小朋友发饼干假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j]>=g[i],我们可以将这个饼干 j 分配......
  • day08-字典
    字典(Dict)是一种可变、无序的数据类型;那等等...我们回忆一下,字符串列表元祖是什么样的?字符串不可变,有序列表可变,有序元祖不可变,有序如何判断有序和无序呢,我首先确定在字符串、列表、元祖篇我们都讲到了切片取值,说明他们都是有顺序的,而字典是无序的,说明字典无法通过切片取值,......