一、题目描述
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.
二、解题思路动态规划,定义一个数组f,f[i]表示以nums[i]结尾的序列的最长递增子序列的长度。则f[i]等于max{f[j],(j<i&&nums[j]<nums[i])}+1。f[i]中最大的值即为结果,算法复杂度为 O(n2) 。
三、代码实现
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int> f(nums.size(),0);
if(nums.size()==0) return 0;
f[0]=1;
for(int i=1;i<nums.size();i++){
int max=0;
for(int j=0;j<i;j++){
if(nums[i]>nums[j]&&f[j]>max)
max = f[j];
}
f[i]=max+1;
}
sort(f.begin(),f.end());
return f[f.size()-1];
}
};
精简版的代码
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n=nums.size();
if(n==0)return 0;
if(n==1)return 1;
vector<int> dp(n,1);
int res=1;
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){
if(nums[i]>nums[j])
dp[i]=max(dp[i],dp[j]+1);
}
res=max(dp[i],res);
}
return res;
}
};
四、改进
思路:动态规划,定义一个数组f,其中f[i]表示长度为i+1的最长递增子串的最小末尾数。当读取传入的每一个数时,从头开始遍历数组f,遇到的第一个比传入的数大的数,则将数组f该位置的值更换为传入的值,如果新传入的值比f中的每一个值都大,则将该值存入f尾部。最后f.size()即为结果。该算法的时间复杂度为O(n log n) 。
实现:
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int> f;
if(nums.size()==0)
return 0;
f.push_back(nums[0]);
for(int i=1;i<nums.size();i++){
bool change =false;
for(int j=0;j<f.size();j++){
if(nums[i]<=f[j]){
f[j]=nums[i];
change=true;
break;
}
}
if(!change)
f.push_back(nums[i]);
}
return f.size();
}
};