博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
leetcode: 最长上升子序列
阅读量:4662 次
发布时间:2019-06-09

本文共 1670 字,大约阅读时间需要 5 分钟。

题目描述:

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

 

示例:

输入: [10,9,2,5,3,7,101,18]

输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:

可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。

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

 

思路分析:

思路一:根据题目的提示,利用动态规划,可以用O(N^2)的复杂度解这题。直接利用一个dp数组,用从后往前的方式存每个元素当前的最长上升序列,更新的状态转移方程就是dp[i] = max(dp[i], dp[j]+1),这里j的取值是从i+1到dp.size()。

思路二:由于题目的进阶要求是需要将复杂度降到O(NlogN),logn顺利成章会想到用二分查找来降低这个复杂度。实际上这部分的思想是维护一个tail数组,遍历nums数组时,每次都在tail数组中去找大于当前值的树,若有则替换,若没有则将当前值加入tail数组。进行替换的原因是在后续的查找中,可以找到更长的子序列,由于当前的tail中的元素更小了。而实际上,只有在添加新元素时会改变最长子序列的大小,因此这个tail数组的长度始终维持在当前最长子序列的长度。这里在查找数用到了二分查找,代码中直接调用了lower_bound()函数。关于这个函数的说明如下:

第一个first参数是一段连续空间的首地址,last是连续空间末端的地址,val是要查找的值。调用lower_bound()的前提是这段连续的空间里的元素是有序(递增)的。
然后lower_bound()的返回值是第一个大于等于val的值的地址,用这个地址减去first,得到的就是第一个大于等于val的值的下标
同时注意区分另一个upper_bound函数,这个返回值是第一个大于val值的地址。
 

代码:

思路一:

1 class Solution { 2 public: 3     int lengthOfLIS(vector
& nums) { 4 if(nums.size()==0) 5 return 0; 6 vector
dp(nums.size(), 1); 7 for(int i=nums.size()-1; i>=0; i--) 8 { 9 for(int j=i+1; j
nums[i])12 {13 dp[i] = max(dp[i], dp[j]+1);14 }15 }16 }17 int max = 0;18 for(int i=0; i
max)21 max = dp[i];22 }23 return max;24 }25 };

思路二:

1 class Solution { 2 public: 3     int lengthOfLIS(vector
& nums) { 4 if(nums.size()==0) 5 return 0; 6 vector
res; 7 for(int i=0; i

 

转载于:https://www.cnblogs.com/LJ-LJ/p/11128590.html

你可能感兴趣的文章
纸片折叠
查看>>
js类型判断:typeof与instanceof
查看>>
实验 8
查看>>
Django学习笔记--数据库中的单表操作----增删改查
查看>>
[洛谷P5075][JSOI2012]分零食
查看>>
第三次作业(第四次不要电梯了吧)
查看>>
mustache语法
查看>>
[Python] 怎么把HTML的报告转换为图片,利用无头浏览器
查看>>
WebGL之通过外部传入a_PontSize值改变点着色器vshader内置变量gl_PointSize的值
查看>>
怎么样调整FreeBSD时区问题
查看>>
Linux CentOS 7的图形界面安装(GNOME、KDE等)
查看>>
大理石
查看>>
python执行外部程序的常用方法小结
查看>>
微信二维码生成
查看>>
linux中 ll 和ls 区别
查看>>
有关js中能否使用equals来判断相等的问题
查看>>
(十八)多线程
查看>>
bzoj4580: [Usaco2016 Open]248
查看>>
HTML5 VS. Flash&Flex? – 浅谈Flash/Flex/HTML 5技术选型
查看>>
响应者链条
查看>>