最长递增子序列

87 阅读1分钟

问题描述

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。
例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

子问题最优解推出大问题最优解。

题解

定义状态:定义子问题

dp[i]: 表示nums中,以nums[i]为结尾的最长递增子序列

状态转移方程:描述子问题之间的联系,需分类讨论:

image.png

考虑往dp[0...i-1]中的最长递增子序列后面加一个num[i]
dp[j]代表以nums[j]为结尾的最长递增子序列
如果nums[i]>nums[j],把nums[i]放在nums[j]后面,形成更长的递增子序列,取其中最长的。

代码

public static int solution(int[] nums) {
    int max = 1;
    // dp[i]: 表示nums中,以nums[i]为结尾的最长递增子序列
    int[] dp = new int[nums.length];
    dp[0] = 1;
    for (int i = 1; i < nums.length; i++) {
        dp[i] = 1;
        for (int j = 0; j < i; j++) {
            // 抉择
            if (nums[i] > nums[j]) {
                // 有多个结果,取最优
                dp[i] = Math.max(dp[i], dp[j] + 1);
            }
        }
        max = Math.max(max, dp[i]);
    }
    return max;
}