算法题解之贪心法

Wiggle Subsequence

最长扭动子序列

思路1:动态规划。状态dp[i]表示以nums[i]为末尾的最长wiggle子序列的长度。时间是O(n^2).

 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 }
View Code

思路2:贪心法。把数组看作一个波浪形,则由起点,终点,波峰,波谷构成的序列就是最长扭动子序列。时间是O(n),空间是O(1)。

 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 }
View Code
原文地址:https://www.cnblogs.com/coldyan/p/6120263.html