【代码随想录day 27】 力扣 376. 摆动序列
视频讲解:https://www.bilibili.com/video/BV17M411b7NS/?vd_source=a935eaede74a204ec74fd041b917810c
文档讲解:https://programmercarl.com/0376.%E6%91%86%E5%8A%A8%E5%BA%8F%E5%88%97.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE
力扣题目:https://leetcode.cn/problems/wiggle-subsequence/
同样使用贪心算法寻找局部最优解从而找出全局最优解,我们只需要找出每个节点峰值,删除单调增或单调减的节点就可以了,这就涉及到判断节点前后的单调性,最基本的,当prediff > 0 && curdiff < 0或者prediff < 0 && curdiff > 0.
这只是理想情况,还会引出3种特殊情况:
1. 上下有平坡
如图所示,这时候需要统一规则,只留一个节点就可以了,我们这里留最右侧节点,即情况为:prediff = 0 && curdiff < 0 要记录一个峰值,因为他是把之前相同的元素都删掉留下的峰值。
所以我们的判断条件为:(preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)
2.首位元素
如果数组只有两个元素,就没有单调性一说了,当然可以拿出来讨论,如果只有两个元素,且数值不相等,就说明是摆动序列,但是如果向融入代码里,可以考虑链表的头插法类似的方法,我们假设前面有一个元素和第一个元素相等,这就形成了上下有平坡的情况,这种情况就满足prediff = 0 && curdiff < 0 或者prediff = 0 && curdiff > 0,自然就融入代码中了。
3.单调有平坡
如图所示,是由这种情况出现的,那么按照我们的方法在第三个2也会判断是一个节点,那要怎么做呢?
我们发现其实prediff和curdiff的值没那么重要,重要的是单调性,如果单调性一样,prediff变不变没有什么所谓,如果单调性变了,prediff才需要变,这里我们把prediff的更新放在遇到单调性改变的节点中就可以了。
class Solution {
public:int wiggleMaxLength(vector<int>& nums) {//剪枝if(nums.size() == 1){return 1;}int prediff = 0;int curdiff = 0;int result = 1;//开始遍历for(int i = 0; i < nums.size() - 1; i++){curdiff = nums[i + 1] - nums[i];if(prediff >= 0 && curdiff < 0 || prediff <= 0 &&curdiff > 0){result++;prediff = curdiff;}}return result;}
};