Description:
Given a sequence of integers, find the longest increasing subsequence (LIS).
You code should return the length of the LIS.
Example
For [5, 4, 1, 2, 3], the LIS is [1, 2, 3], return 3
For [4, 2, 4, 5, 3, 7], the LIS is [4, 4, 5, 7], return 4
For "ABCD" and "EACB", the LCS is "AC", return 2.
Challenge
Time complexity O(n^2) or O(nlogn)
Clarification
Solution:
class Solution {
public:
/**
* @param nums: The integer array
* @return: The length of LIS (longest increasing subsequence)
*/
int longestIncreasingSubsequence(vector<int> nums) {
auto sz = (int)nums.size();
if (sz == 0) return 0;
vector<int> dp(sz, 0);
vector<int> cost(sz+1, 0); // const[i] = min{nums[t], dp[t] = i}
dp[0] = 1;
cost[1] = nums[0];
int cnt = 1; // counter of cost
int rc = 1;
for (int i = 1; i < sz; ++i) {
if (nums[i] < cost[1]) {
cost[1] = nums[i];
dp[i] = 1;
} else if (nums[i] >= cost[cnt]) {
++cnt;
cost[cnt] = nums[i];
dp[i] = cnt;
} else {
int k = binarySearch(cost, 1, cnt, nums[i]);
cost[k] = nums[i];
dp[i] = k;
}
rc = max(rc, dp[i]);
}
return rc;
}
private:
int binarySearch(vector<int>& nums, int l, int r, int target) {
auto sz = (int)nums.size();
if (sz == 0) return 0;
while (l <= r) {
int mid = l+r>>1;
if (nums[mid] > target) r = mid-1;
else if (nums[mid] < target) l = mid+1;
else return mid;
}
return l;
}
};