ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-04-16 20:33:37  阅读:188  来源: 互联网

标签:nums 题解 递增 let 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有