最长递增子序列 DP JAVA

本文介绍了一种求解最长递增子序列的高效算法,通过动态规划结合二分查找,实现O(nlogn)的时间复杂度。以数组arr={4,2,3,1,5,6,4,8,9}

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目的意思是在一个数组中,求出最长递增的一个序列长度。

以数组 arr = {4,2,3,1,5,6,4,8,9}; 为例:

先创建一个dp数组 ,用dp数组的下标来表示最长递增子序列的长度

程序执行顺序:

遍历arr数组

dp[1] = 4;

dp[1]=4>2 所以更新 dp[1] = 2

dp[1]=2<3 所以3加入dp  dp[2] = 3

dp[2]=3>1  此时遍历dp数组  由于dp数组是递增排列的  找到第一个大于1的数 并更新该数   即 dp[1]=2>1   所以dp[1] = 1

dp[2] = 3 <5   所以 dp[3] = 5

dp[3] = 5<6   所以 dp[4] = 6

dp[4] = 6 >4   遍历dp数组    找到第一个大于4的数  即为dp[3] = 5   此时更新dp[3] = 4

.......(以此类推下标  即为最递增子序列的度)

/**
 * @author wl
 * @Data 2020-05-09 20:47
 */
public class LIS_最长递增子序列 {
    public static void main(String[] args) {
        int[] arr = {4,2,3,1,5,6,4,8,9};
        System.out.println(Lcs(arr));
    }
    /**
     * nlog(n)
     * @param arr
     * @return
     */
    static int Lcs(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+1] = arr[i];
                p++;
            }else{
                //可以用二分法优化
              /*  for (int j = 0; j <= p; j++) {
                    if (dp[j]>arr[i]){
                        dp[j]=arr[i];
                    }
                }*/
               //优化后
                int flag = erfen(dp,arr[i],0,p);
                if (flag!=-1){
                    dp[flag] = arr[i];
                }
            }
        }
        return p;
    }
    static int erfen(int[]dp,int v,int l,int r){
        while (l <= r){
            int mid = (r+l)>>1;
            if (dp[mid]>v){
                r=mid;
            }else {
                l=mid+1;
            }
            if (l==r && dp[mid]>v)
                return l;
        }
        return -1;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值