• 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)),还有很大的优化空间,不过今天没有时间继续研究了,留作下次再看:力扣官方解答


    提交结果

    CS专业在读,热爱编程。
    专业之外,喜欢阅读,尤爱哲学、金庸、马尔克斯。
  • 相关阅读:
    洛谷P2334
    线性基
    6.28 模拟赛解题报告
    左偏树
    哈夫曼树 Huffman
    CSP/NOIP 之前还需要学/复习的东西
    CF718C
    6.13 模拟赛结题报告
    关于模拟退火
    『笔记』网络流
  • 原文地址:https://www.cnblogs.com/jmhwsrr/p/14126200.html
Copyright © 2020-2023  润新知