LeetCode376. 摆动序列

题目

分析

摘自Carl大佬总结

局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值。实际操作上,其实连删除的操作都不用做,因为题目要求的是最长摆动子序列的长度,所以只需要统计数组的峰值数量就可以了(相当于是删除单一坡度上的节点,然后统计长度)但题目只要求返回i长度,所以并不需要真的删除。最后统计局部峰值即可。

关键是统计峰值也不好统计有一定的技巧。下面的错误代码就是自己在统计峰值时的错误

错误代码(主要思想是去除峰底和峰顶之间坡上的元素)

 1 class Solution {
 2 public:
 3     int wiggleMaxLength(vector<int>& nums) {
 4         int res = nums.size();
 5         //边界处理
 6         if(nums.size() == 0 || nums.size() == 1) return nums.size(); //没有元素
 7         if(nums.size() == 2 && nums[0] == nums[1]) return nums.size()-1; //两个相同元素
 8         if(nums.size() == 3 && nums[0] == nums[1] && nums[1] == nums[2]) return 1;
 9         
10         for(int i = 1;i <nums.size()-1;i++){  //检查从第二个元素到倒数第二个元素
11             if(nums[i] > nums[i-1] && nums[i+1] < nums[i]) {cout<<nums[i]<<" ";continue;}
12             if(nums[i] < nums[i-1] && nums[i+1] > nums[i]) {cout<<nums[i]<<" ";continue;}
13             if(i > 1 && nums[i] == nums[i-1] && nums[i] == nums[i+1]) {cout<<nums[i];continue;}
14             res--;
15         }
16         return res;
17     }
18 };

上面代码主要总差1,是因为连续三个相同值、连续两个相同值出错,总之讨论繁琐。从总个数中删除非极值点不好做。

正确代码

 1 class Solution {
 2 public:
 3     int wiggleMaxLength(vector<int>& nums) {
 4         if(nums.size() <= 1) return nums.size();
 5         int res = 1;//初始为1,默认最右段有峰值
 6         int cur = 0;//当前对的差值
 7         int pre = 0;//上一对的差值,前置0
 8         for(int i = 1;i < nums.size();i++){
 9             cur = nums[i] - nums[i-1];
10             if((cur > 0 && pre <= 0) || (cur < 0 && pre >= 0)){
11                 res++;
12                 pre = cur;
13             }
14         }
15         return res;
16     }
17 };
原文地址:https://www.cnblogs.com/fresh-coder/p/14368734.html