brute force做的话,递归来做,每个元素在不在subsequence中,时间复杂度O(2^n)
方法一:DP
由于只需要求个数,不需要把subsequence求出来,很自然想到dp
dp[i] 表示以 a[i] 为结尾的最长字串的长度,
dp[i] = max(dp[j]+1) ∀0<=j<i
最后的结果就是 max(dp[i]) ∀i
时间复杂度 O(n^2)
class Solution { public: int lengthOfLIS(vector<int>& nums) { vector<int> dp(nums.size(),1); for (int i=0;i<nums.size();++i){ for (int j=0;j<i;++j){ if (nums[j]<nums[i]) dp[i] = max(dp[i], dp[j]+1); } } int res=0; for (int x:dp) res = max(res,x); return res; } };
方法二:Binary Search
类似模拟的方法,二分寻找大于等于当前元素的下标。时间复杂度O(nlogn),详见
https://leetcode.com/problems/longest-increasing-subsequence/solution/
https://segmentfault.com/a/1190000003819886
class Solution { public: int lengthOfLIS(vector<int>& nums) { vector<int> tmp; for (int num:nums){ if (tmp.empty()||num>tmp.back()) tmp.push_back(num); else{ int index=lower_bound(tmp,num); tmp[index] = num; } } return tmp.size(); } int lower_bound(vector<int> &a, int x){ int low=0, high=a.size(); while (low<high){ int mid=(low+high)/2; if (a[mid]<x) low=mid+1; else high=mid; } return low; } };