[LEETCODE] 376. Wiggle Subsequence

376.Wiggle Subsequence 解題報告
A sequence of numbers is called a wiggle sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a wiggle sequence.

For example, [1,7,4,9,2,5] is a wiggle sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast, [1,4,7,2,5] and [1,7,4,5,5] are not wiggle sequences, the first because its first two differences are positive and the second because its last difference is zero.

Given a sequence of integers, return the length of the longest subsequence that is a wiggle sequence. A subsequence is obtained by deleting some number of elements (eventually, also zero) from the original sequence, leaving the remaining elements in their original order.

Examples:
Input: [1,7,4,9,2,5]
Output: 6
The entire sequence is a wiggle sequence.

Input: [1,17,5,10,13,15,10,5,16,8]
Output: 7
There are several subsequences that achieve this length. One is [1,17,10,13,10,16,8].

Input: [1,2,3,4,5,6,7,8,9]
Output: 2
Follow up:
Can you do it in O(n) time?

因爲題目要求用O(n) time,所以這裏我選擇了貪心算法。
它的原理是:如果連續3個數都是升序或者降序的話(1,2,3 或者 3,2,1),那麼它的wiggle subsequence 就不會增加。
代碼如下:

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        //greedy
        if (nums.size() < 2) return nums.size();
        int i = 1;
        int count = 1;
        while (i < nums.size() && nums[i] == nums[i - 1]) i++;
        bool diff = nums[i] > nums[i - 1];
        for (; i < nums.size(); i++) {
            if (diff)
              while (i + 1 < nums.size() && nums[i] <= nums[i + 1]) i++;
            else
              while(i + 1 < nums.size() && nums[i] >= nums[i + 1]) i++;
            diff = !diff;
            count += 1;
        }
        return count;
    }
};

還有一種方法是用DP:這個方法的時間複雜度是O(n^2)
狀態轉移方程

dp[i][0]=max{dp[j][1]}+1 當nums[i]>nums[j]

dp[i][1]=max{dp[j][0]}+1 當nums[i]

public class Solution {  
    public static int wiggleMaxLength(int[] nums)  
    {  
        int len=nums.length;  
        if(len<=1)  
            return len;  

        int[][] dp=new int[len][2];  
        dp[0][0]=1;  
        dp[0][1]=1;  

        for(int i=1;i<len;i++)  
        {  

            int a=Integer.MIN_VALUE;  
            int b=Integer.MIN_VALUE;  
            for(int k=i-1;k>=0;k--)  
            {  
                if(nums[i]>nums[k])  
                    a=Math.max(a, dp[k][1]);  
                else if(nums[i]<nums[k])  
                    b=Math.max(b, dp[k][0]);  
            }  


            dp[i][0]=(a>Integer.MIN_VALUE?a+1:1);  
            dp[i][1]=(b>Integer.MIN_VALUE?b+1:1);  

        }  

        return Math.max(dp[len-1][0], dp[len-1][1]);  
    }  
}  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章