最长上升子序列
来源:互联网 发布:淘宝店铺免费采集软件 编辑:程序博客网 时间:2024/05/24 01:49
问题描述:
输入一串数字(无序),求最长上升子序列的长度,如输入“3,1,4,2,3,5”,输出4,因为最长上升子序列为“1,2,3,5”。
解法:
- 动态规划
用动态规划的思想,假设p[i]表示以nums[i]为末尾的最长上升子序列长度,则有如下最优子结构:时间复杂度O(n^2),空间复杂度O(n)。p[i]={1max0≤k<i(p[k] | nums[k]<nums[i])+1i=0i=1,2,...,n−1
class Solution {public: vector<int> p; int getLength(vector<int>& nums, int k) { //求以p[k]为末尾的最长上升子序列长度 if (p[k] != 0) return p[k]; else if (k == 0) p[0] = 1; else { int maxL = 0; for (int i = 0; i < k; i++) { int temp = getLength(nums, i); if (nums[k] > nums[i] && temp > maxL) maxL = temp; } p[k] = maxL + 1; } return p[k]; } int lengthOfLIS(vector<int>& nums) { p.assign(nums.size(),0); int maxL = 0; for (int i = 0; i < nums.size(); i++) { int temp = getLength(nums, i); if (temp > maxL) maxL = temp; } return maxL; }};
O(nlogn)解法,一个神奇的方法
同样引入数组p,但p[i]所表示的含义不一样,p[i]指上升子序列长度为i+1时的尾数,举个例子“1,3,1,2,3”,p[0]=1,p[1]=2,p[2]=3,p是个递增的数组。
从左至右考察数组nums,当考察nums[k]时,从左至右遍历数组p,查找首个p[i]>=nums[k]:- 如果没有找到,则数组p在末尾新添成员,值为nums[k],表示多了一个更长的上升子序列,且序列尾数为nums[k];
- 如果找到首个p[i]>=nums[k],则p[i]要被替换成nums[k],因为只有p[i]变得更小,才能在后面的考察中找到更长的子序列。拿刚刚的例子来说,p[1]也可以为3,为什么后来为2,因为只有这样,p[2]才会被新添进来,成为更长的子序列;
如果是普通的遍历查找,那时间复杂度还是O(n^2),但如果是二分查找,时间复杂度就是O(nlogn)。
class Solution {public: int binarySearch(vector<int>& p, int s) { //从左至右遍历数组p,查找首个p[i]>=s的下标 int l = 0, r = p.size() - 1; while (l <= r) { int mid = (l + r) / 2; if (p[mid] >= s) r = mid - 1; else l = mid + 1; } return r + 1; }//如果没有找到返回接下来要放的位置 int lengthOfLIS(vector<int>& nums) { vector<int> p; for (int i = 0; i < nums.size(); i++) { int temp = binarySearch(p, nums[i]); if (temp == p.size()) p.push_back(nums[i]); else p[temp] = nums[i]; } return p.size(); }};
0 0
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 随机抽样问题(蓄水池问题)
- POJ 1276 Cash Machine
- Properties&JavaBean
- Python 2.7视频安装
- Stage 3D:结缘、性能对比及相关开发框架推荐
- 最长上升子序列
- CPP_Basic_Code_P8.1-PP8.8.7
- Qt类内部有一个该类类型指针
- Selenium自动化测试框架的搭建 (转)
- linux基本语法7
- LintCode 把排序数组转换为高度最小的二叉搜索树
- Linux操作系统使用及linux常用命令
- dom4j
- 对JVM的理解