經典題目,最長遞增子序列。
有O(n^2)效率,還有O(n*logn)效率的。
O(n^2)的效率很好理解的啦,就是大家最常見的那種DP
O(n*logn) 的方法是維護一個遞增的棧,這個棧不等於最長遞增子序列。但是數組的長度一定是等於最長遞增子序列的長度的。
遍歷原始數組,每次的操作是把當前元素和遞增棧的最後一個元素作比較,如果大於直接入棧,否則就找到大於等於它的最小的元素,然後替換掉。這個思想的來源是貪心,而不是DP
O(n^2)
class Solution {
public:
int dp[5005];
int lengthOfLIS(vector<int>& nums) {
int ans=0;
for(int i=0;i<nums.size();i++)
{
dp[i]=1;
for(int j=i-1;j>=0;j--)
{
if(nums[i]>nums[j])
dp[i]=max(dp[i],dp[j]+1);
}
ans=max(ans,dp[i]);
}
return ans;
}
};
O(n*logn)
class Solution {
public:
int dp[5005];
int len;
int lengthOfLIS(vector<int>& nums) {
len=0;
for(int i=0;i<nums.size();i++)
{
if(len==0||nums[i]>dp[len-1])
dp[len++]=nums[i];
else
{
int index = find(nums[i]);
dp[index]=nums[i];
}
}
return len;
}
int find(int x)
{
int l = 0;
int r = len-1;
while(l<=r)
{
int mid = (l+r)/2;
if(dp[mid]<x)
{
l = mid+1;
}
else if(dp[mid]>x)
{
r = mid-1;
}
else
return mid;
}
return l;
}
};