Java 求解最长递增子序列

Posted 南淮北安

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 求解最长递增子序列相关的知识,希望对你有一定的参考价值。

一、题目

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。

例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

二、题解

最长上升子序列是动规的经典题目,这里dp[i]是可以根据dp[j] (j < i)推导出来的,那么依然用动规五部曲来分析详细一波:

(1)确定 dp 数组以及下标的含义

dp[i]表示i之前包括i的最长上升子序列。

(2)确定递推表达式

位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 + 1 的最大值。

位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 + 1 的最大值。

所以:if (nums[i] > nums[j]) dp[i] = Math.max(dp[i], dp[j] + 1);

注意这里不是要 dp[i] 与 dp[j] + 1 进行比较,而是我们要取 dp[j] + 1 的最大值。

(3)确定 dp 数组的初始化

每一个 i,对应的 dp[i](即最长上升子序列)起始大小至少都是是1.

(4)确定遍历顺序

dp[i] 是有0到i-1各个位置的最长升序子序列 推导而来,那么遍历i一定是从前向后遍历。

三、代码

class Solution 

    public int lengthOfLIS(int[] nums) 
        if (nums != null && nums.length <= 1) 
            return nums.length;
        
        // dp[i] 表示0-i 的最长子序列长度
        int[] dp = new int[nums.length];
        // 初始值都为1
        Arrays.fill(dp, 1);
        int res = Integer.MIN_VALUE;
        for (int i = 1; i < nums.length; i++) 
            // dp[i] 为 0-i 子序列长度的最大值
            for (int j = 0; j < i; j++) 
                if (nums[i] > nums[j]) 
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                
            
            res = Math.max(res, dp[i]);
        
        return res;
    

四、总结

以上是关于Java 求解最长递增子序列的主要内容,如果未能解决你的问题,请参考以下文章

Java 求解最长连续递增序列

动态规划之最大递增子序列

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

求解最长递增子序列(LIS) | 动态规划(DP)+ 二分法

动态规划之----最长递增子序列

笔试题1:最长严格递增子序列