最长上升子序列

问题是:

给定一个无序的整数数组,找到其中最长上升子序列的长度。

示例:

输入: [10,9,2,5,3,7,101,18]
输出: 4 
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4

说明:

  • 可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
  • 你算法的时间复杂度应该为 O(n2) 。

进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?

首先是 复杂度为 O(n^2) 的解法:

/**
 * @param {number[]} nums
 * @return {number}
 */
var lengthOfLIS = function(nums) {
    let dp = [];//dp[i]表示以nums[i]为末尾的最长上升子序列的长度
    let max = -Infinity;
    if(nums.length==0){
        return 0;
    }
    for(let i=0;i<nums.length;i++){
        dp[i] = 1;
        for(let j=0;j<i;j++){
            if(nums[j]<nums[i]){
                dp[i] = Math.max(dp[i],dp[j]+1);
            }
        }
        max = Math.max(dp[i],max);
    }
    return max;
};

利用动态规划的方法:

dp[i] 表示以 nums[i] 为末尾的最长上升子序列的长度,它首先包含 nums[i] 自己(即 dp[i] 首先赋值为1),然后比较 nums[i] 之前的数(下标为 j ),如果比 nums[i] 小,那么比较 dp[i] 和 dp[j]+1 的大小,较大的那个更新为 dp[i] 的值。

状态转移方程为:

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

posted @ 2019-07-19 22:30  湛蓝的家  阅读(113)  评论(0编辑  收藏  举报