仅为个人记录复盘学习历程,解题思路来自代码随想录
代码随想录刷题笔记总结网址:
代码随想录
376. 摆动序列
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。
输入数据:整型数组nums。
关键思路:
使用贪心法解决该问题。
局部最优,删除单调坡度上的中间节点(非两端节点),这个坡度就可以有两个局部峰值。
全局最优,拥有最多的局部峰值。
实际操作不需要真的删除节点,只需要将中间节点忽略,不统计在内即可。
通过遍历数组,计算nums[i]-nums[i-1]和nums[i+1]-nums[i]的大小来判断是否需要将该结点统计在内。如果(nums[i]-nums[i-1])>0&&(nums[i+1]-nums[i]<0)或(nums[i]-nums[i-1]<0)&&(nums[i+1]-nums[i]>0)需要统计,这里排除了等于0的情况,等于0的情况在这基础上讨论。
等于0的情况分三种:
用来统计的result默认为1,用来默认数组最右边有一个局部峰值。假设pre=nums[i]-nums[i-1],cur=nums[i+1]-nums[i]。
上下坡中有平坡。
2-2-2-2 / \ 1 1
假设删除左边三个2,那么需要统计1,最右边的2(最右边的1由统计的result初始化表示)。
对于最左边的1,pre=0(初始化为0),cur=1>0,需要记录在内,所以当(nums[i]-nums[i-1]<=0)&&(nums[i+1]-nums[i]>0)需要在我们判断是否记录的条件内,而对于最右边的2,pre=2-2=0,cur=1-2=-1<0,同样需要记录在内,所以(nums[i]-nums[i-1])>=0&&(nums[i+1]-nums[i]<0)同样需要在我们判断是否记录的条件内。所以判断是否记录的条件扩展为:nums[i]-nums[i-1]<=0)&&(nums[i+1]-nums[i]>0)||nums[i]-nums[i-1])>=0&&(nums[i+1]-nums[i]<0)。
数组首尾两端。
2 \ 5
根据我们的判断条件:对于2,pre=0,cur=3,记录在内,再加上result初始化为1,结果为2,符合我们的需求。
单调坡中有平坡。
5 \ 2-2-2-2 \ 1
按照我们的判断条件,对于这样,在5统计了一次,在最右边的2统计了一次,由于result初始化为1,所以统计出来为3,实际上应该为2,这是由于pre的更新被平缓的2影响,只需要在统计的时候再更新pre=cur,就可以避免平缓的2对pre的更新造成影响。
代码大致如下:
public int wiggleMaxLength(int[] nums) {
int result=1;
int cur=0;
int pre=0;
for(int i=0;i<nums.length-1;i++){
cur=nums[i+1]-nums[i];
if((pre>=0&&cur<0)||(pre<=0&&cur>0)){
result++;
pre=cur;
}
}
return result;
}
标签:pre,cur,nums,int,随想录,result,序列,日记,刷题
From: https://blog.csdn.net/weixin_73939095/article/details/143991054