算法题解之贪心法
Wiggle Subsequence
最长扭动子序列
思路1:动态规划。状态dp[i]表示以nums[i]为末尾的最长wiggle子序列的长度。时间是O(n^2).
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class Solution { 2 public int wiggleMaxLength(int[] nums) { 3 if (nums == null || nums.length == 0) { 4 return 0; 5 } 6 int[] pos_dp = new int[nums.length]; 7 int[] neg_dp = new int[nums.length]; 8 9 pos_dp[0] = 1; 10 neg_dp[0] = 1; 11 for (int i = 1; i < pos_dp.length; i++) { 12 neg_dp[i] = 1; 13 pos_dp[i] = 1; 14 for (int j = 0; j < i; j++) { 15 if (nums[j] > nums[i]) { 16 neg_dp[i] = Math.max(neg_dp[i], pos_dp[j] + 1); 17 } else if (nums[j] < nums[i]) { 18 pos_dp[i] = Math.max(pos_dp[i], neg_dp[j] + 1); 19 } 20 } 21 } 22 23 int res = 0; 24 for (int i = 0; i < pos_dp.length; i++) { 25 res = Math.max(Math.max(pos_dp[i], neg_dp[i]), res); 26 } 27 return res; 28 } 29 }
思路2:贪心法。把数组看作一个波浪形,则由起点,终点,波峰,波谷构成的序列就是最长扭动子序列。时间是O(n),空间是O(1)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class Solution { 2 public int wiggleMaxLength(int[] nums) { 3 if (nums == null || nums.length == 0) { 4 return 0; 5 } 6 7 int j = 0; 8 while (j < nums.length - 1 && nums[0] == nums[++j]) {} 9 if (j == nums.length - 1 && nums[j] == nums[0]) { 10 return 1; 11 } 12 13 int res = 2; 14 boolean up = nums[j] > nums[0]; 15 for (int i = j + 1; i < nums.length; i++) { 16 if ((up && nums[i] < nums[i - 1]) || (!up && nums[i] > nums[i - 1])) { 17 res++; 18 up = !up; 19 } 20 } 21 return res; 22 } 23 }