目录

LeetCode-376.-摆动序列-java题解

LeetCode 376. 摆动序列 java题解

只要不满足摆动条件,就不更新count和prediff

当 prevDiff 取等号时,比如 prevDiff == 0,在这种情况下,如果 currDiff > 0,说明从持平状态转变为上升状态,这是一种有效的摆动起始情况;同理,如果 currDiff < 0,则是从持平状态转变为下降状态,也属于有效的摆动起始情况。例如序列 [1, 1, 2],第一个 1 到第二个 1 时 prevDiff = 0,第二个 1 到 2 时 currDiff > 0,这种从持平到上升的情况应该被视为摆动的开始,所以需要包含 prevDiff == 0 的情况

从摆动子序列的定义角度:摆动子序列要求序列中的元素按照一定的规律交替出现上升和下降。当序列中只有一个元素时,它可以被看作是一个特殊的摆动子序列,虽然不存在真正意义上的上升或下降交替,但它本身可以作为摆动子序列的起始点或基础,具有唯一性和确定性,符合摆动子序列的最小单元概念,所以定义其摆动数为 1。

class Solution {
    public int wiggleMaxLength(int[] nums) {
        int len=nums.length;
        if(len==1) return 1;
        if(len==2){
            return nums[0]==nums[1]?1:2;
        }
        int count=1;
        int prediff=0;
        int curdiff=0;
        for(int i=1;i<len;i++){
            curdiff=nums[i]-nums[i-1];
            if(curdiff>0){
                if(prediff<=0){
                    count++;
                    prediff=curdiff;
                }
            }
            else if(curdiff<0){
                if(prediff>=0){
                    count++;
                    prediff=curdiff;
                }
            }
            else{
                //平坡,跟上个数一样,不改变
            }
        }
        return count;
    }
}

动态规划

// DP
class Solution {
    public int wiggleMaxLength(int[] nums) {
        // 0 i 作为波峰的最大长度
        // 1 i 作为波谷的最大长度
        int dp[][] = new int[nums.length][2];

        dp[0][0] = dp[0][1] = 1;
        for (int i = 1; i < nums.length; i++){
            //i 自己可以成为波峰或者波谷
            dp[i][0] = dp[i][1] = 1;

            for (int j = 0; j < i; j++){
                if (nums[j] > nums[i]){
                    // i 是波谷
                    dp[i][1] = Math.max(dp[i][1], dp[j][0] + 1);
                }
                if (nums[j] < nums[i]){
                    // i 是波峰
                    dp[i][0] = Math.max(dp[i][0], dp[j][1] + 1);
                }
            }
        }

        return Math.max(dp[nums.length - 1][0], dp[nums.length - 1][1]);
    }
}

很容易可以发现,对于我们当前考虑的这个数,要么是作为山峰(即 nums[i] > nums[i-1]),要么是作为山谷(即 nums[i] < nums[i - 1])。

设 dp 状态dp[i][0],表示考虑前 i 个数,第 i 个数作为山峰的摆动子序列的最长长度 设 dp 状态dp[i][1],表示考虑前

i 个数,第 i 个数作为山谷的摆动子序列的最长长度 则转移方程为:

dp[i][0] = max(dp[i][0], dp[j][1] + 1),其中0 < j < i且nums[j] <

nums[i],表示将 nums[i]接到前面某个山谷后面,作为山峰。 dp[i][1] = max(dp[i][1], dp[j][0]

  • 1),其中0 < j < i且nums[j] > nums[i],表示将 nums[i]接到前面某个山峰后面,作为山谷。 初始状态: