leetcode记录:最长递增/减子序列

一、最长递增/减子序列问题

给定数组arr,返回arr的最长递增/减子序列或者子序列长度。

二、分析

1.返回长度

leetcode题解给了dp方法或者贪心二分的方法。
dp方法:
1.确定状态:dp[i]表示的是0到i这一段数组中最长的递减子数组长度。
2.转移方式:从前面寻找可能转移到当前i位置的转移点,比较大小。
以递减序列为例:

package Other.LongestDecreasingSubsequence;

import java.util.Arrays;
public class Solution {
    public static void main(String[] args) {
        int[] arr={9,4,3,2,5,4,3,2,7,5,56,0,1};
        System.out.println(new Solution().LongestDecreasingSubsequence(arr));
    }
    public int LongestDecreasingSubsequence(int[] arr){
        int[] dp=new int[arr.length];
        dp[0]=1;
        int maxres=1;
        for (int i = 1; i < arr.length; i++) {
            dp[i] = 1;
            for (int j = 0; j < i; j++) {
                if (arr[i]<arr[j])
                    dp[i]=Math.max(dp[i],dp[j]+1);
            }
            maxres = Math.max(maxres, dp[i]);
        }
        System.out.println(Arrays.toString(dp));

        return maxres;
    }

}

时间复杂度O(n2)

使用贪心加二分的方法可以将复杂度优化至
O(nlogn)

2.返回数组

如果需要返回这个数组,只需要从后往前找就可以了,当然,观察dp数组可知,这个序列并不唯一。

package Other.LongestDecreasingSubsequence;

import java.util.Arrays;

public class Solution {
    public static void main(String[] args) {
        int[] arr={9,4,3,2,5,4,3,2,7,5,56,1};
        System.out.println(Arrays.toString(new Solution().LongestDecreasingSubsequence(arr)));
    }
    public int[] LongestDecreasingSubsequence(int[] arr){
        int[] dp=new int[arr.length];
        dp[0]=1;
        for (int i = 1; i < arr.length; i++) {
            for (int j = 0; j < i; j++) {
                if (arr[i]<arr[j])
                    dp[i]=Math.max(dp[i],dp[j]+1);
            }
        }
        System.out.println(Arrays.toString(dp));
        int[] res=new int[dp[arr.length-1]];
        int j=res.length-1;
        int cur=dp[dp.length-1];
        for (int i = arr.length-1; i >= 0; i--) {
            if (dp[i]==cur){
                res[j]=arr[i];
                j--;
                cur--;
            }
        }
        return res;
    }

}

如果需要返回全部的序列,可以用回溯。

import java.util.Arrays;
public class Solution3 {
    public static void main(String[] args) {
        int[] arr={9,4,3,2,5,4,3,2,7,5,56,0,1};
        new Solution3().LongestDecreasingSubsequence(arr);
    }
    public void LongestDecreasingSubsequence(int[] arr){
        int[] dp=new int[arr.length];
        dp[0]=1;
        int maxres=1;
        for (int i = 1; i < arr.length; i++) {
            dp[i] = 1;
            for (int j = 0; j < i; j++) {
                if (arr[i]<arr[j])
                    dp[i]=Math.max(dp[i],dp[j]+1);
            }
            maxres = Math.max(maxres, dp[i]);
        }
        System.out.println(Arrays.toString(dp));
        back(dp,arr,maxres,new int[maxres],dp.length-1);
    }

    public void back(int[] dp, int[] arr, int maxres,int[] res,int index){
        if (maxres==0){
            System.out.println(Arrays.toString(res));
            return;
        }
        if (index<0)
            return;

        for (int i = index; i >= 0; i--) {
            if (dp[i]==maxres){
                res[maxres-1]=arr[i];
                back(dp,arr,maxres-1,res,i);
                res[maxres-1]=0;
            }
        }
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值