Leetcode 300 题 最长递增子序列

题目描述

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

子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

示例:
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。


思路分析

这道题求最长上升子序列,我们可以定义一个 dp 数组,dp[i] 表示以 nums[i] 为最后一个元素时,最长上升子序列的数量,要想知道 dp[i],我们必然要先从 0 ~ i - 1 元素中,查找到所有数值小于当前 nums[i] 的元素。然后再在这些元素中,找到最长上升子序列数长度最大的元素nums[j],而我们要求的 dp[i] 就等于 dp[j] + 1。其过程如下所示:
1、首先 dp[0] 默认等于 1,尽管只有一位,也是需要自立门户,长度为1的。
2、接下来要获得 dp[1] 的值,nums[1] 在其前面没有找到比自己小的元素,因此只能自立门户,dp[1] = 1。
Leetcode 300 题 最长递增子序列_第1张图片
3、接下来要获得 dp[2] 的值,nums[2] 在前面依旧没有找到比自己小的值,仍然自立门户,dp[2] = 1。
Leetcode 300 题 最长递增子序列_第2张图片
4、接下来需要获得 dp[3] 的值,nums[3] 之前有一个元素 nums[2] 比自己小,因此 dp[3] = dp[2] + 1 = 2,表示到以 nums[3] 为结尾,最长上升子序列长度为 2,即 nums[2] -> nums[3]。
Leetcode 300 题 最长递增子序列_第3张图片
5、接着要获得 dp[4] 的值,nums[4] 之前有一个元素 nums[2] 比自己小,因此 dp[4] = dp[2] + 1 = 2,表示以 nums[4] 为结尾,最长上升子序列长度为 2,即 nums[2] -> nums[4]。
Leetcode 300 题 最长递增子序列_第4张图片
6、接着要获得 dp[5] 的值,nums[5] 之前有元素 nums[2]、nums[3]、nums[4] 比自己小,其中,dp[3] 的数值是最大的,因此,dp[5] = dp[3] + 1 = 3,表示以 nums[5] 为结尾,最长上升子序列长度为 3,即 nums[2] -> nums[3] -> nums[5]。
Leetcode 300 题 最长递增子序列_第5张图片
7、接下来需要获得 dp[6] 的值,nums[6] 之前的所以元素都比它小,因此在之前的元素中找到 dp[5] 的数值最大,dp[6] = dp[5] + 1 = 4,表示以 nums[6] 结尾,最长上升子序列长度为 4,即 nums[2] -> nums[3] -> nums[5] -> nums[6]。
Leetcode 300 题 最长递增子序列_第6张图片
8、接下来获得 dp[7] 的值,比 nums[7] 小的元素有 nums[0] ~ nums[5],找到其中 dp 数值最大的元素 nums[5],因此 dp[7] = dp[5] + 1 = 4,表示以 nums[7] 为结尾,最长上升子序列长度为 4,即 nums[2] -> nums[3] -> nums[5] -> nums[7]。
Leetcode 300 题 最长递增子序列_第7张图片
虽然找到了全部的 dp 值,那我们能直接以最后一个 dp 值作为结果输出吗,当然不行,因为用上面的例子,dp[last] 表示的是以 18 为结尾最长上升子序列,我们要找的最长上升子序列并不一定以最后一个元素为结尾,因此我们还需要再对 dp 数组做一遍遍历,找到 dp 的最大值。
Leetcode 300 题 最长递增子序列_第8张图片


代码描述

下面使用 Java 进行代码描述:

class Solution {
    public int lengthOfLIS(int[] nums) {
        int m = nums.length;
        int[] dp = new int[m];
        dp[0] = 1;
        int maxLength = 1;
        for (int i = 1; i < m; i++) {
            dp[i] = 1;
            for (int j = 0; j < i; j++) {
                if (nums[j] < nums[i]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            maxLength = Math.max(maxLength, dp[i]);
        }

        return maxLength;
    }
}

欢迎关注

技术公众号:【小猿君的算法笔记】,一起学习,一起成长。


原文链接

Leetcode 300 题 最长递增子序列

你可能感兴趣的:(Leetcode,编程历程,Java,算法,数据结构,java,leetcode,动态规划)