LeetCode第300题:最长递增序列

357 阅读2分钟

题干

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

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

示例 1:

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

解法:动态规划

一道经典的动规问题。

我们dp[i]的含义为,在原数组的i处的递增序列个数。所以我们计划先算出所有的递增序列个数,再取出最大值。

问题就在于如何取得递增序列的个数。

我们需要循环当前元素之前的数,如果遇到小于当前元素的元素则+1,并且与当前的dp[i]对比,取大值。这样最终就可以取得dp[i]的值。

我们的动规方程是:

if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1)

注意这里并不是比较的含义是寻找j种的最大值。因为我们一直在向后迭代,所以dp[i]就是上一个的dp[i]+1的较大值。所以最终依次遍历结束我们就可以获得最终的dp[i]

执行用时:204 ms, 在所有 JavaScript 提交中击败了55.46%的用户

内存消耗:39.1 MB, 在所有 JavaScript 提交中击败了94.29%的用户

/**
 * @param {number[]} nums
 * @return {number}
 */
var lengthOfLIS = function (nums) {
    let len = nums.length;
    if(len==1){
        return 1
    }
    let dp = new Array(len).fill(1);
    dp[0] = 1;
    let maxNum=0;
    for (let i = 1; i < len; i++) {
        for (let j = 0; j < i; j++) {
            if (nums[j] < nums[i]) {
                //这里是计算dp[i]当前的值
                dp[i] = Math.max(dp[j] + 1, dp[i])
            }
        }
        // 
        maxNum=Math.max(maxNum,dp[i])
    }
    return maxNum;
};