300. **Longest Increasing Subsequence (the longest increasing subsequence)
https://leetcode.com/problems/longest-increasing-subsequence/description/
topic description
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
-10^4 <= nums[i] <= 10^4
Follow up:
- Could you come up with the
O(n^2)
solution? - Could you improve it to
O(n log(n))
time complexity?
Code
Given an unsorted integer array, find the length of the longest increasing subsequence in it. The longest increasing subsequence is very impressive~ First consider using dynamic programming to solve it. The definition dp[i]
means nums[i]
with Increment the length of the subsequence. Note that “ nums[i]
ends with . In order to obtain the state transition equation, it is necessary to examine dp[i]
the relationship between and other elements. We find that for j < i
,
- If
nums[i] > nums[j]
, then youdp[j]
cannums[i]
insert at the end of the corresponding longest increasing subsequence, which still satisfies the property of increasing at this time, at this timedp[i] = dp[j] + 1 (nums[i] > nums[j])
; - And if
nums[i] <= nums[j]
, it means thatnums[i]
cannot be added todp[j]
the longest increasing subsequence corresponding to , and because thedp[i]
definition of needs to "nums[i]
end with ", thendp[i] = 1
it means that the longest increasing subsequence in the arraynums[i]
ending is actuallynums[i]
itself , with a size of 1. (Therefore,dp
when initializing, it is1
very )
Summarizing the above analysis, the state transition equation can be obtained as:
for (int j = i - 1; j >= 0; -- j) {
if (nums[i] > nums[j])
dp[i] = max(dp[i], dp[j] + 1);
}
So the code is as follows:
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int res = 0;
vector<int> dp(nums.size(), 1);
for (int i = 1; i < nums.size(); ++ i) {
for (int j = i - 1; j >= 0; -- j) {
if (nums[i] > nums[j])
dp[i] = max(dp[i], dp[j] + 1);
}
res = max(res, dp[i]);
}
return res;
}
};
For example, the following lists the array nums
and the dp value corresponding to each element in the array:
nums: 4, 10, 4, 3, 8, 9
dp: 1, 2, 1, 1, 2, 3
Finally, find the maximum value dp
in 3
, that is, the length of LIS is 3, such as 3, 8, 9
or 4, 8, 9
.
Follow up
In this question, it is mentioned O(n log(n))
that the complexity of can be used to solve it. The idea is to try to find the longest increasing subsequence in the array. The specific method is:
Use the sequence r
to save nums
the longest increasing subsequence in . Traverse each element nums
of v
, and then find r
in v
corresponding to lower_bound
, that is, the first value greater than or equal v
to .
- If it is not found
r
inv
, it meansv
that isr
greater than all elements in , so it can bev
added tor
the end of , - And if there is an element
r
in (*p
indicated by in the code) that is greater than or equal tov
, then usev
to replace this element. In this way, on the one hand, if is*p
originally equal tov
, then it has no effect; and if is*p
originally greater thanv
, then it will be updated tov
after , which means that the value becomes smaller, and new elements are inserted in the future, and there are more opportunities to make the sequence grow.
code show as below:
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int> r;
for(auto v : nums) {
auto p = std::lower_bound(r.begin(), r.end(), v);
if (r.end() == p)
r.push_back(v);
else
*p = v;
}
return r.size();
}
};