Given an integer array nums, return the length of the longest strictly increasing subsequence.
A subsequence is a sequence that can be derived from an array by deleting some or no elements without changing the order of the remaining elements. For example, [3,6,2,7] is a subsequence of the array [0,3,1,6,2,2,7].
Example 1:
Input: nums = [10,9,2,5,3,7,101,18] Output: 4 Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.
Example 2:
Input: nums = [0,1,0,3,2,3] Output: 4
Example 3:
Input: nums = [7,7,7,7,7,7,7] Output: 1
Constraints:
1 <= nums.length <= 2500-104 <= nums[i] <= 104
Follow up:
- Could you come up with the
O(n2)solution? - Could you improve it to
O(n log(n))time complexity?
Related Topics:
Binary Search, Dynamic Programming
Similar Questions:
- Increasing Triplet Subsequence (Medium)
- Russian Doll Envelopes (Hard)
- Maximum Length of Pair Chain (Medium)
- Number of Longest Increasing Subsequence (Medium)
- Minimum ASCII Delete Sum for Two Strings (Medium)
- Minimum Number of Removals to Make Mountain Array (Hard)
dp[i] = max( dp[j] + 1 | 0 <= j < i && A[j] < A[i] )
dp[0] = 1
// OJ: https://leetcode.com/problems/longest-increasing-subsequence/
// Author: github.com/lzl124631x
// Time: O(N^2)
// Space: O(N)
class Solution {
public:
int lengthOfLIS(vector<int>& A) {
if (A.empty()) return 0;
int N = A.size();
vector<int> dp(N, 1);
for (int i = 1; i < N; ++i) {
for (int j = 0; j < i; ++j) {
if (A[j] < A[i]) dp[i] = max(dp[i], dp[j] + 1);
}
}
return *max_element(begin(dp), end(dp));
}
};We use a vector<int> v to store the LIS. v is always sorted.
For each n in A, we first find the first v[i] that is >= n.
If such v[i] exists, we replace v[i] with n. Such operation won't break the LIS but make this LIS easier to extend.
Otherwise, n is greater than all values in v, we can simply append n into v.
// OJ: https://leetcode.com/problems/longest-increasing-subsequence/
// Author: github.com/lzl124631x
// Time: O(NlogN)
// Space: O(N)
// Ref: https://leetcode.com/problems/longest-increasing-subsequence/solution/
class Solution {
public:
int lengthOfLIS(vector<int>& A) {
vector<int> v;
for (int n : A) {
auto i = lower_bound(begin(v), end(v), n);
if (i == end(v)) v.push_back(n);
else *i = n;
}
return v.size();
}
};1671. Minimum Number of Removals to Make Mountain Array (Hard) is a great bidirectional extension of this problem.