1. 程式人生 > 實用技巧 >2020-12-12 擺動序列

2020-12-12 擺動序列

題目


解決方法

這道題目與之前做過的最長上升子序列很類似,我在這篇部落格中也寫到過。

動態規劃

方法與最長上升子序列類似,不過需要注意對序列擺動方向進行判斷。

程式碼實現:

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if (nums.size() < 2) {
            return nums.size();
        }
        
        if (nums.size() == 2) {
            if (nums[0] == nums[1])
                return 1;
            return nums.size();
        }
        
        #define UP 1    // 該元素相比之前的元素是上擺
        #define DOWN 0  // 下襬
        #define NO 2    // 無擺動,即與之前的所有元素相等
        int direct;
        vector<vector<int>> dp(nums.size(), vector<int>(2, 0)); 
        
        // 使用一個二維陣列來存放資訊,每個元素又包含了陣列對應位置的元素及之前元素中的最長擺動序列長度與擺動方向資訊
        dp[0][0] = 1;
        dp[0][1] = NO;
        if (nums[0] == nums[1]){    // 為前dp陣列的前兩個元素賦值
            dp[1][0] = 1;
            dp[1][1] = NO;
        } else{
            nums[0] > nums[1] ? dp[1][1] = DOWN : dp[1][1] = UP;
            dp[1][0] = 2;
        }

        for (int i = 2; i < nums.size(); i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] == nums[j]) // 相等則不做操作
                    continue;
                if (dp[j][1] == UP) {   // 若為上擺,則nums[i]必須比nums[j]小才可能組成擺動序列
                    if (nums[i] < nums[j]){
                        if (dp[i][0] < dp[j][0] + 1) {
                            dp[i][0] = dp[j][0] + 1;
                            dp[i][1] = DOWN;
                        }
                        continue;
                    }
                } else if (dp[j][1] == DOWN) {  // 若為下襬,...
                    if (nums[i] > nums[j]) {
                        if (dp[i][0] < dp[j][0] + 1) {
                            dp[i][0] = dp[j][0] + 1;
                            dp[i][1] = UP;
                        }
                        continue;
                    }
                } else {    // 若無擺動, ...
                    if (nums[i] > nums[j]) {
                        if (dp[i][0] < dp[j][0] + 1) {
                            dp[i][0] = dp[j][0] + 1;
                            dp[i][1] = UP;
                        }
                    } else {
                       if (dp[i][0] < dp[j][0] + 1) {
                            dp[i][0] = dp[j][0] + 1;
                            dp[i][1] = DOWN;
                        }
                    }
                }
            }    
        } 

        int max = dp[0][0];
        for (int i = 1; i < nums.size(); i++) {
            if (dp[i][0] > max){    // 取出最長擺動序列長度
                max = dp[i][0];
            }
        }

        return max;
    }
};

時間複雜度為\(O(n^2)\),還有很大的優化空間,不過今天沒有時間繼續研究了,留作下次再看:力扣官方解答


提交結果