其他分享
首页 > 其他分享> > 最长递增子序列-DP+打牌

最长递增子序列-DP+打牌

作者:互联网

题目

300. 最长递增子序列

难度中等1533

给你一个整数数组 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 。
提示:
	1 <= nums.length <= 2500
	-104 <= nums[i] <= 104

子串 VS 子序列

  1. 子串:一定是连续的

  2. 子序列可以不用连续,但是要注意元素原来的相对顺序。

    (大白话就是:在你前面的还是在你前面。术语叫做:稳定!)

解法一:动态规划

动态规划解法思想:

  1. 找到状态和选择
  2. 明确dp数组、函数的定义 (在本题中:dp[i] 表示以nums[i]这个数结尾的最长递增子序列的长度)
  3. 寻找状态之间的关系 (经常会使用数学归纳法)
/**
 * @param {number[]} nums
 * @return {number}
 */
var lengthOfLIS = function(nums) {
  // base case: 最长递增子序列初始值为1,就是要包括自己
    const dp = new Array(nums.length);
    dp.fill(1);
  
    for(let i = 0; i < nums.length; ++i) {
        // 找到在i前面比nums[i]小的数字
        for(let j = 0; j < i; ++j  ) {
          // 找到比nums[i]小的书,形成新的递增子序列,新的递增子序列在原来的基础上加1
            if (nums[i] > nums[j]) {
                dp[i] = Math.max(dp[i],dp[j] + 1);
            }
        }
    }
  	// apply这函数挺好用的,可以用来改变参数的传递。
    return Math.max.apply(Math,dp);
};

解法二:二分搜索

解法核心思想:
给牌分堆:

var lengthOfLIS = function(nums) {
    let top = [];
    let piles = 0; // 记录牌的堆数

    for (let i = 0; i < nums.length; ++i) {
        // 当前牌,nums[i] 表示牌的大小
        let poker = nums[i];

        // 牌堆进行一个二分查找
        let left = 0,
            right = piles;
        while (left < right) {
            let mid = parseInt((left + right) / 2);
            if (top[mid] > poker) {
                right = mid;
            } else if (top[mid] < poker) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        if (left == piles) piles++;
        top[left] = poker;
    }
    return piles;
};

以上解法思想基本来自于 《labuladong算法小抄》,这是一本很”实在“, 可操作性强的书,十分适合菜鸟入门学习leetcode。

刷leetcode的时候,大家要注意一个问题是,题不只是刷一遍,要完全理解一个问题至少刷个四五遍!而且还有一个问题是,你是来学习别人的解法的,你不会做,很正常!!不会就看题解,看官方题解,看图解题解,看labuladong题解,leetcode国际站题解!反正就是发掘一切能够学习的资料。如果你坐在那里半天耗一个题目完全没有必要,因为你不是来发明解法的!你是来学习解法的,学习别人优秀的解题思想的!

参考

- 《labuladong算法小抄》
- leetcode官方题解

标签:nums,题解,递增,let,DP,打牌,序列,解法,dp
来源: https://www.cnblogs.com/rookie123/p/14668604.html