1、题目来源:选自LeetCode 376:摆动序列
2、题目描述:
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。
例如, [1,7,4,9,2,5]
是一个摆动序列,因为差值 (6,-3,5,-7,3)
是正负交替出现的。相反, [1,4,7,2,5]
和 [1,7,4,5,5]
不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。
3、题目分析:
摇摆子序列的定义可以看出,这些点如果在坐标中表示出来的话,形成的形状是一个折线,而且没经过一个点折线都会改变上升或者下降的趋势,如果序列中有一段连续的上升或者连续的下降的情况,则我们利用贪心算法去折线的首位元素,这样更加有可能使尾部后面的那一个元素成为摇摆子序列的下一个元素。
4、代码实现:
1 public int wiggleMaxLength(int[] nums) { 2 //进行特殊情况下的边界检测 3 if(nums.length<2){ 4 return nums.length; 5 } 6 //定义三个状态值 7 final int BEGIN = 0; 8 final int UP = 1; 9 final int DOWN = 2; 10 int START = BEGIN; 11 int Max_len = 1; 12 /** 13 * 循环遍历整个数组,根据每个元素和前一个元素的大小关系确定状态值,并根据状态值决 14 * 定最长子序列的长度是否增加。 15 */ 16 17 for (int i = 1; i < nums.length; i++) { 18 switch (START) { 19 //开始时刻比较当前元素和前一个元素的大小关系,然后确定状态值是上升还是下降 20 case BEGIN: 21 //若前一个元素较小,则是上升状态,将状态值改为上升UP 22 if (nums[i - 1] < nums[i]) { 23 START = UP; 24 Max_len++; 25 //若前一个元素较大,则是下降状态,将状态值改为下降DOWN 26 } else if (nums[i - 1] > nums[i]) { 27 START = DOWN; 28 Max_len++; 29 } 30 break; 31 32 /** 33 * 若当前状态已经是上升状态,那么下一个元素只能是下降状态的时候符合摇摆序列 34 * 的定义,其他情况都是不满足摇摆序列的定义的情况 35 */ 36 case UP: 37 if (nums[i - 1] > nums[i]) { 38 START = DOWN; 39 Max_len++; 40 } 41 break; 42 43 /** 44 * 若当前状态已经是下降状态,那么下一个元素只能是上升状态的时候符合摇摆 45 * 序列的定义,其他情况都是不满足摇摆序列的定义的情况 46 */ 47 case DOWN: 48 if (nums[i - 1] < nums[i]) { 49 START = UP; 50 Max_len++; 51 } 52 break; 53 } 54 } 55 56 return Max_len; 57 }