暴力枚举:时间复杂度O(2^N)
动态规划,这道题和【最大子段和】那道题很相似
第i个状态dp[i]代表以第i个元素结尾的最长上升子序列的长度。nums[i]一定是dp[i]所对应的最长上升子序列中最大的元素。
最终结果为dp[0]...dp[n-1]中的最大值
初始化最长上升子序列的长度LIS = 1;
从1到N-1,循环i,计算dp[i]:
从0到i-1,循环J,若nums[i]>nums[j],说明nums[i]可放到nums[j]的后面,组成上升子序列:
若dp[i] < dp[j] +1: dp[i] = dp[j] + 1
LIS就是dp数组中最大的。
复杂度O(N^2):
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
if(nums.size() == 0)
return 0;
vector<int> dp(nums.size(),0);
dp[0] = 1;
int res = dp[0];
for(int i = 1;i<nums.size();++i)
{
dp[i] = 1;//以第i个字符结尾的序列,至少长度1
for(int j = 0;j < i ;++j)
{//如果第i位大于第j位的数,就可以把它接在后面,并且接到后面后,长度更长了,就更新长度
if(nums[i] > nums[j] && dp[i] < dp[j] +1)
dp[i] = dp[j] +1;
}
if(res < dp[i])
res = dp[i];
}
return res;
}
};
方法2:
设置一个栈(vector实现),stack[i]代表长度为i+1的上升子序列最后一个元素的最小可能取值,即若要组成长度为i+2的上升子序列,需要一个大于stack[i]的元素。最终栈的长度,即为最长上升子序列长度
nums = [1 3 2 3 1 4]
1.设置一个栈(vector实现),将Nums[0]push进去
2.从1至n-1遍历nums数组:若nums[i]>栈顶,将nums[i]入栈。否则,从栈底遍历到栈顶,若遍历时,栈中有元素大于等于nums[i],就用Nums[i]替换这个元素,跳出循环
3.返回栈大小
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
if(nums.size() == 0)
return 0;
vector<int> st;
st.push_back(nums[0]);
for(int i = 1;i < nums.size(); ++i)
{
if(nums[i] > st.back())
{
st.push_back(nums[i]);
}else{
for(int j = 0;j< st.size();++j)
{
if(nums[i] <= st[j])//上升子序列是严格递增的,所以有=号,假如现在子序列是1-2-3,此时的Num是1,如果没有=号,就变成了1-1-3
{
st[j] = nums[i];
break;
}
}
}
}
return st.size();
}
};
对方法2优化,时间复杂度O(n*logn)
class Solution {
public:
//利用二分查找确定Num[i]该插入在栈的哪个位置
int binary_search(vector<int> nums,int target)
{
int index = -1;
int begin = 0;
int end = nums.size() - 1;
while(index == -1)
{
int mid = (begin + end)/2;
if(target == nums[mid])
index = mid;
else if(target < nums[mid])
{
if(mid == 0 || target>nums[mid-1])
{
index = mid;
}
end = mid - 1;
}else if(target > nums[mid])
{
if(mid == nums.size()-1 || target < nums[mid+1])
index = mid + 1;
begin = mid + 1;
}
}
return index;
}
int lengthOfLIS(vector<int>& nums) {
if(nums.size() == 0)
return 0;
vector<int> st;
st.push_back(nums[0]);
for(int i = 1;i < nums.size(); ++i)
{
if(nums[i] > st.back())
{
st.push_back(nums[i]);
}else{
//相比优化前修改的地方:
int pos = binary_search(st,nums[i]);
st[pos] = nums[i];
}
}
return st.size();
}
};