LeetCode376摆动序列

摆动序列》》》
在这里插入图片描述

这道题,求摆动序列的最长长度和之前做过的一道求序列的最长上升子序列类似,不同的是本题无法用一个数组来记录以i结尾的最长上升子序列,因为摆动数组的每一个元素既可以是最长摆动子序列下降后的元素,也可以是上升后的元素

因此,可以用两个数组维护,最长上升子序列与最长下降子序列,对于当前元素进行判断,若nums[i]-nums[j]则应该从nums[j]所处的下降序列中找最长

  /**
     * 本题和最长上升子序列类似
     *    不同的是本题无法用一个数组来记录以i结尾的最长上升子序列,因为摆动数组的没每一个元素既可以是
     *    最长摆动子序列下降后的元素,也可以是上升后的元素
     *
     *    nums = [1,17,5,10,13,15,10,5,16,8]
            nums[2] 即数值 5, 既可以属于 [1, 5] 与前一个相比为上升, 也可以属于 [1, 17, 5] 与前一个相比为下降, 由于不知道后面数子的情况, 所以 5 属于这两种不同情况的数值也必须保留
     所以, 可以使用 up 和 down 两个数组分别记录 n 属于这两种状态下的最长摆动序列
     定义即是: up 代表以 nums[i] 结尾的最长摆动序列的长度, 并且 nums[i] 位置的元素相比于上一个元素是上升的, 那么上例中 up[2] 为 2 down[2] 为 3
     *
     *
     *
     * @param nums
     * @return
     */
    public int wiggleMaxLength1(int[] nums){

        if(nums.length==0) return 0;

		//当前元素处于上升的序列
        int[] dpUp = new int[nums.length];
        //当前元素处于下降的序列
        int[] dpDown = new int[nums.length];
        for(int i=0;i<nums.length;i++){
            dpDown[i]=1;
            dpUp[i]=1;
        }

        for(int i=1;i<nums.length;i++){

            for(int j=0;j<i;j++){
             // 说明 nums[j] -> nums[i]
                // 是一个下降的过程,
                // 那么只有在最长摆动序列中 nums[i] 位置的元素属于上升元素时,
                // 此处的 nums[i] 才可以把它给延长, 并且延长后 nums[i] 位置本身是属于下降的元素
                if(nums[j] > nums[i]){
                    dpDown[i]=Math.max(dpDown[i],dpUp[j]+1);
                }else if(nums[j]<nums[i]) {//说明是上升的元素
                    dpUp[i] = Math.max(dpUp[i], dpDown[j] + 1);

                } //元素相等的话则不作任何处理

            }

        }

        int max = 0;
        //从记录中找到最长的,这部分代码也可以融入到前面的动态规划中,动态更新全局最大值
        for(int i=0;i<nums.length;i++){
            max =Math.max(dpDown[i],dpUp[i]);

        }

        return max;
    }




2020/8/4



 /**定义两个变量up:代表上升摆动序列的长度 。down:代表下降摆动序列的长度。
            1 nums[i]>nums[i-1]则说明这个摆动序列在上升,此时上升摆动序列长度=下降摆动序列+1(加1是加的nums[i])
            2 nunm[i]<nums[i-1]则说明这个摆动序列在下降,此时下降摆动序列长度=上升摆动序列+1(加1是加的nums[i])**/
    public int wiggleMaxLength1(int[] nums) {
        if(nums.length<2) return nums.length;
        int down=1;
        int up=1;
        for(int i=1;i<nums.length;i++){
            if(nums[i]>nums[i-1]){
                up=down+1;
            }else if(nums[i]<nums[i-1]){
                down=up+1;
            }
        }
        return Math.max(up,down);
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值