您的位置:首页 > 产品设计 > UI/UE

[300]Longest Increasing Subsequence

2015-11-03 20:20 441 查看
【题目描述】

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

For example,

Given 
[10, 9, 2, 5, 3, 7, 101, 18]
,

The longest increasing subsequence is 
[2, 3, 7, 101]
, therefore the length
is 
4
. Note that there may be more than one LIS combination, it is only necessary
for you to return the length.

Your algorithm should run in O(n2) complexity.

Follow up: Could you improve it to O(n log n) time complexity?

【思路】

经典的最长子序列的题目。

第一种方法是o(n^2)的。len[i]表示到nums[i]结尾的序列中最长递增子序列的长度,pre[i]记录的是该最长递增子序列结尾的元素的下标。如果比i小的j中有满足对应最长递增子序列结尾的元素比nums[i]小,而且len[j]+1>len[i],那么则更新pre[i]和len[i],同时和maxnum比较,如果比maxnum大,更新maxnum,遍历结束的时候返回maxnum。

第二种方法是对第一种方法的改进,因为采用了二分搜索,所以是O(nlogn)的。pre[i]里记录的是长度为i的最长递增子序列结尾的元素。给pre[0]赋值无限小,pre[1]赋值nums[0],从第二个元素开始遍历,对于第i个元素,对长度为0到maxlen的最长子序列进行二分搜索,找到长度最长的且结尾元素即pre[j]比num[i]小的最长子序列,更新长度为j+1的结尾元素为nums[i],并且把长度与maxlen比较,如果大于则更新maxlen。结束时返回maxlen。

【代码】

class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n=nums.size();
if(n==0) return 0;
vector<int> pre(n,0);
vector<int> len(n,1);
int maxnum=1;
for(int i=0;i<n;i++){
pre[i]=i;
}
for(int i=1;i<n;i++){
for(int j=0;j<i;j++){
if(nums[i]>nums[pre[j]]&&len[j]+1>len[i]){
pre[i]=i;
len[i]=len[j]+1;
if(maxnum<len[i]){
maxnum=len[i];
}
}
}
}
return maxnum;
}
};

class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n=nums.size();
if(n==0) return 0;
vector<int> pre(n,0);
//vector<int> len(n,1);
//int maxnum=1;
pre[0]=INT_MIN;
pre[1]=nums[0];
int low,high,mid;
int maxlen=1;
for(int i=1;i<n;i++){
low=0;
high=maxlen;
while(low<=high){
mid=(low+high)/2;
if(nums[i]>pre[mid]) low=mid+1;
else high=mid-1;
}
pre[low]=nums[i];
if(low>maxlen) maxlen++;
}
return maxlen;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: