以LeetCode-300为例:
O(n^2)解法:
dp数组表示以i结尾的最长递增子序列的长度
class Solution {
public:int lengthOfLIS(vector<int>& nums) {const int size = nums.size();if (size == 0) { return 0; } vector<int> dp(size, 1);int res = 1;for (int i = 1; i < size; ++i) {for (int j = 0; j < i; ++j) {if (nums[j] < nums[i]) {dp[i] = max(dp[i], dp[j]+1);}}res = max (res, dp[i]);}return res;}
};
O(nlogn)解法:
tails[i]数组定义:长度为i+1最长递增子序列的最小值末尾值
以nums[4,5,6,3]为例
len = 1 : [4], [5], [6], [3] => tails[0] = 3
len = 2 : [4, 5], [5, 6] => tails[1] = 5
len = 3 : [4, 5, 6] => tails[2] = 6
很容易判断tails数组递增,可以应用二分法
(1) if x is larger than all tails, append it, increase the size by 1
(2) if tails[i-1] < x <= tails[i], update tails[i]
class Solution {
public:int lengthOfLIS(vector<int>& nums) {vector<int> tails(nums.size(),0);int size=0;for(int t=0;t<nums.size();t++){int i=0,j=size;while(i!=j){int mid=(i+j)/2;if(tails[mid]<nums[t])i=mid+1;else j=mid; // 注意这里为了取到右端的值}tails[i]=nums[t];if(i==size)size++;}return size;}
};