力扣376. 摆动序列

题目来源(力扣):

https://leetcode.cn/problems/wiggle-subsequence/description/

题目描述:

给出一个数组,找出一个子数组,使得子数组中的元素是一大一小相互交替的。该子数组应该尽量长,求长度tot。

基本思路:

比较直观是思路是在原数组中找到那些发生大小转折的节点,选出这些节点构成的子数组就是符合题目的。
(开头节点特殊处理,将其视为特殊的状态)
例如

[1, 5, 4, 5, 6, 7, 6, 5, 8, 9]
 |  |  |  |        |     |   

所谓大小转折的节点,可以通过一个变量tai来记录之间的数字是上升的(1)还是下降的(-1),
如果和之前的状态tai不一致,说明遇见了符合条件的节点,修改tai的值,并且总节点数tot+1;

代码实现:

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int tot=1;//nums[0]
        int tai=0;//当前的状态 1上升 -1下降 0初态
        for(int i=1;i<nums.size();i++){
            if(nums[i]==nums[i-1])continue;
            if(nums[i]>nums[i-1]){
                if(tai!=1){//转折点累计
                    tai=1;
                    tot++;
                }
            }
            else{
                if(tai!=-1){//转折点累计
                    tai=-1;
                    tot++;
                }
            }
        }
        return tot;
    }
};

时间复杂度

O(n)

补充

《代码随想录》中,在理论层面选取的是峰值节点,如下

[1, 5, 4, 5, 6, 7, 6, 5, 8, 9]
 |  |  |        |     |     |

实际上和我的选取方式是“一样的”
[1, 5, 4, 5, 6, 7, 6, 5, 8, 9]
 |  |  |  |        |     |   

对于以中间这部分为例,
  [.., 4, 5, 6, 7, ... ]
我选取的是坡度性质发生改变的第一个节点5,而书的作者选取的是坡度性质发生改变的最后一个节点(即山峰山谷)
即我选取的是5,而作者选取的是7
最后是等效的,都总计tot=6

最有意思的事是,虽然《代码随想录》(2021年12月第1版第1次印刷)在理论层面选取的是峰值节点,
但是最后代码采用的方式还是选取的第一个转账点(即我的方法)
只是在细节上有所不同,最后答案都是正解

条条大路通罗马~

posted @ 2024-11-08 15:24  HB_Computer  阅读(23)  评论(0)    收藏  举报