最长递增子序列的动态规划的求解二

1. 问题描述:求解最长递增子序列的长度

输入:第一行输入的是数组的长度 

第二行开始输入的是数组中的元素

输出:最长递增子序列的长度

输入 4 2 3 1 5 6 

输出 4 (因为 2 3 5 6组成了最长递增子序列)

2. 使用之前的动态规划的解法的时间复杂度还是有点高,为O(n ^ 2),于是有人又想出了动态规划另外的优化解法,我们可以借鉴其中的思路来开拓我们的思维和更好地理解动态规划

思路是:dp[i]表示的是长度为i的最长递增子序列的末尾的那个数

举个例子:先初始化dp[0]为数组中第一个元素的值,即dp[0]  =  4,定义一个指针p用来记录当前递增子序列的位置,从数组的第二个元素开始比较当前arr[i]与当前指针指向的dp数组的位置的值的大小,假如arr[i] > dp[p]那么说明当前的字符可以构成更长的递增子序列那么我们应该更新dp数组,指针往下移动,然后把当前的arr[i]的值赋值给dp[++p],假如arr[i] < dp[p]说明当前字符不能够构成更长的递增子序列,此时需要进行元素的替换,为什么进行替换呢?因为当前更小的元素更有利于最长递增子序列的贡献,所以扫描dp数组指向位置以及之前的位置假如arr[i] 大于dp[p]那么我们将其dp[p] 替换为arr[i]

最后返回的是指针p指向的位置,这也是与之前动态规划的一般解法不同的点

3. 具体的代码如下:

import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int arr[] = new int[n];
        for(int i = 0; i < n; i++){
            arr[i] = sc.nextInt();
        }
        System.out.println(solution(arr));
        sc.close();
    }
    private static int solution(int[] arr){
        int dp[] = new int[arr.length + 1];
        dp[1] = arr[0];
        int p = 1;
        for(int i = 1; i < arr.length; i++){
            if(arr[i] > dp[p]){
                dp[++p] = arr[i];
            }else{
                for(int j = 0; j <= p; j++){
                    if(dp[j] > arr[i]){
                        dp[j] = arr[i];
                    }
                }
            }
        }
        return p;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值