leetcode300. 最长递增子序列(动态规划)

138 阅读1分钟

要理解动态规划需要先知道“数学归纳法”,即:

证明当n= 1时命题成立。假设n=m时命题成立,那么可以推导出在n=m+1时命题也成立。(m代表任意自然数)

动态规划的思路和这个很像,即:

先求出n=1时的值,再利用这个值求出n=2时的值,再利于n=1,n=2的值求出n=3的值......此次类推

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

题目链接

我们先求出n=0时的值:

var nums = [0,3,1,6,2,2,7];

var dp = []; // 用来存储结算得到的值。
dp[0] = 1; // n=0的值

利用dp[0]计算n=1的值:

if (nums[1] > nums[0]) {
    dp.push(dp[0] + 1);
} else {
    dp.push(1);
}

利用dp[0],dp[1]计算n=2的值:

var i = 2;
var counter = []; // 临时记录n=2时,每一位的新值
for (var j = 0; j < i; j++) {
    if (nums[i] > nums[j]) {
        counter.push(dp[j] + 1);
    } else {
        counter.push(1);
    }
}
dp.push(Math.max.apply(Math, counter)) // 题目要的是最大值

最终代码:

var lengthOfLIS = function(nums) {
    var dp = [1];

    for (var i = 1; i < nums.length; i++) {
        var counter = [];
        for (var j = 0; j < i; j++) {
            if (nums[i] > nums[j]) {
                counter.push(dp[j] + 1);
            } else {
                counter.push(1);
            }
        }
        dp.push(Math.max.apply(Math, counter))
    }

    return Math.max.apply(Math, dp);
};

参考链接: 动态规划设计:最长递增子序列