题目描述

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

例如,

给出 [10, 9, 2, 5, 3, 7, 101, 18]
最长的上升子序列是 [2, 3, 7, 101],因此它的长度是4。因为可能会有超过一种的最长上升子序列的组合,因此你只需要输出对应的长度即可。

解题思路

用动态规划思想,考虑用一个数组dp记录到当前数字为止,可能的最长上升子序列长度,注意并不一定是当前子序列的解。这样最后返回dp数组的长度即可。具体以上述数组为例:

  • 首先把10加入到dp中,此时最长上升子序列长度为1
  • 下一个数字是9,它比dp中仅有的数字10要小,可知以9为子序列首数字的可能长度要比10长,因此用9替换10
  • 同样把2替换dp中仅有的数字9
  • 加入5时,因为5比2大,所以可以组成最长上升子序列,因此把5加入到2之后
  • 当前数字3比dp中第二个数字5要小,考虑到之后可能出现的上升序列可能小于5,因此用3替换5
  • 加入7时,因为7比dp中最后一个数字3大,所以可以组成最长上升子序列,因此把7加入到3之后
  • 同样加入101到dp
  • 加入18时,按上述规则用18替换101,最后dp数组为[2,3,7,18],因此最长上升子序列长度为4

通过以上顺序,可以总结出dp数组变化规则:

  • 若当前数字大于dp中最后一个数字,则直接插入到最后
  • 找到dp数组中第一个大于当前数字的数,并替换为当前数字
  • 遍历完数组后,dp数组的大小即为最长上升子序列的长度

其中查找dp数组中第一个大于当前数字的数时,可用二分查找降低时间复杂度,这样此解法的总时间复杂度为Ο(nlogn)

代码

 class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int l=nums.size();
vector<int> dp;
if(l==)
return ;
dp.push_back(nums[]);
for(int i=;i<l;i++){
biReplace(dp,nums[i]);
}
return dp.size();
}
void biReplace(vector<int>& dp, int x){
int f=,l=dp.size()-;
if(x>dp[l]){
dp.push_back(x);
return;
}
int m=(f+l)/;
while(dp[m]!=x){
if(dp[m]>x)
l=m-;
else f=m+;
if(f>l){
m=f;
break;
}
m=(f+l)/;
}
dp[m]=x;
}
};

LeetCode 300. 最长上升子序列(Longest Increasing Subsequence)的更多相关文章

  1. 300最长上升子序列 · Longest Increasing Subsequence

    [抄题]: 往上走台阶 最长上升子序列问题是在一个无序的给定序列中找到一个尽可能长的由低到高排列的子序列,这种子序列不一定是连续的或者唯一的. 样例 给出 [5,4,1,2,3],LIS 是 [1,2 ...

  2. [Swift]LeetCode300. 最长上升子序列 | Longest Increasing Subsequence

    Given an unsorted array of integers, find the length of longest increasing subsequence. Example: Inp ...

  3. nlog(n)解动态规划--最长上升子序列(Longest increasing subsequence)

    最长上升子序列LIS问题属于动态规划的初级问题,用纯动态规划的方法来求解的时间复杂度是O(n^2).但是如果加上二叉搜索的方法,那么时间复杂度可以降到nlog(n).  具体分析参考:http://b ...

  4. 动态规划--最长上升子序列(Longest increasing subsequence)

    前面写了最长公共子序列的问题.然后再加上自身对动态规划的理解,真到简单的DP问题很快就解决了.其实只要理解了动态规划的本质,那么再有针对性的去做这方的题目,思路很快就会有了.不错不错~加油 题目描述: ...

  5. 最长递增子序列(Longest increasing subsequence)

    问题定义: 给定一个长度为N的数组A,找出一个最长的单调递增子序列(不要求连续). 这道题共3种解法. 1. 动态规划 动态规划的核心是状态的定义和状态转移方程.定义lis(i),表示前i个数中以A[ ...

  6. 【转】动态规划:最长递增子序列Longest Increasing Subsequence

    转自:https://www.cnblogs.com/coffy/p/5878915.html 设f(i)表示L中以ai为末元素的最长递增子序列的长度.则有如下的递推方程: 这个递推方程的意思是,在求 ...

  7. 算法实践--最长递增子序列(Longest Increasing Subsquence)

    什么是最长递增子序列(Longest Increasing Subsquence) 对于一个序列{3, 2, 6, 4, 5, 1},它包含很多递增子序列{3, 6}, {2,6}, {2, 4, 5 ...

  8. Java实现 LeetCode 300 最长上升子序列

    300. 最长上升子序列 给定一个无序的整数数组,找到其中最长上升子序列的长度. 示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,10 ...

  9. leetcode 300最长上升子序列

    用递归DFS遍历所有组合肯定积分会超时,原因是有很多重复的操作,可以想象每次回溯后肯定会有重复操作.所以改用动态规划.建立一个vector<int>memo,初始化为1,memo[i]表示 ...

随机推荐

  1. mysql-8.0.17-winx64 部署

    1.官网下载mysql-8.0.17-winx64,选择Zip文件格式下载 2.解压到目标路径,我这里是E盘根目录,即E:\mysql8 3.根目录下创建my.ini,内容如下: [mysqld]#端 ...

  2. LaTeX pdf转eps格式

    使用GSview对pdf 进行 eps 转换 1.准备好PDF文件 例如:f1.pdf 2.打开GSview,转换f1.pdf成为f1.ps 打开GSview,File-->Convert--& ...

  3. loj 6031「雅礼集训 2017 Day1」字符串

    loj 注意到每次询问串长度都是给定的,并且询问串长\(k*\)询问次数\(q<10^5\),所以这里面一个东西大的时候另一个东西就小,那么考虑对较小的下功夫 如果\(k\le \sqrt{n} ...

  4. java 周期时期计算

    package org.apple.date; import java.text.SimpleDateFormat; import java.util.Calendar; import java.ut ...

  5. SVM处理多分类问题

    "one-against-one" approach from sklearn import svm X = [[0], [1], [2], [3]] Y = [0, 1, 2, ...

  6. 使用 java 创建你的第一个区块链(第一部分)

    本系列教程的目的是帮助您了解如何开发区块链技术. 在本教程中,我们将: 创建你的第一个(非常)基本的“区块链”. 实施简单的工作证明(采矿)系统. 惊叹于可能性. (我假设您对面向对象编程有基本的了解 ...

  7. 记一次生产环境presto删表失败的问题

    场景,开发用java程序连接presto创建一个表,这个表在hdfs的权限为: 然后用presto去删除这个表 报错,没有权限删除,查看上一级目录权限,发现权限正常 直连hive删表 发现正常. 然后 ...

  8. 隔离技术线程池(ThreadPool)和信号量(semaphore)

    一.首先要明白Semaphore和线程池各自是干什么? 信号量Semaphore是一个并发工具类,用来控制可同时并发的线程数,其内部维护了一组虚拟许可,通过构造器指定许可的数量,每次线程执行操作时先通 ...

  9. Werkzeug(Flask)之Local、LocalStack和LocalProxy

  10. PMBOK :美国的项目管理知识体系

    PMBOK 是Project Management Body Of Knowledge的缩写, 指项目管理知识体系的意思,具体是美国项目管理协会(PMI)对项目管理所需的知识.技能和工具进行的概括性描 ...