300. **Longest Increasing Subsequence (the longest increasing subsequence)

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 you dp[j]can nums[i]insert at the end of the corresponding longest increasing subsequence, which still satisfies the property of increasing at this time, at this time dp[i] = dp[j] + 1 (nums[i] > nums[j]);
  • And if nums[i] <= nums[j], it means that nums[i]cannot be added to dp[j]the longest increasing subsequence corresponding to , and because the dp[i]definition of needs to " nums[i]end with ", then dp[i] = 1it means that the longest increasing subsequence in the array nums[i]ending is actually nums[i]itself , with a size of 1. (Therefore, dpwhen initializing, it is 1very )

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 numsand 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 dpin 3, that is, the length of LIS is 3, such as 3, 8, 9or 4, 8, 9.

Follow upIn 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 rto save numsthe longest increasing subsequence in . Traverse each element numsof v, and then find rin vcorresponding to lower_bound, that is, the first value greater than or equal vto .

  • If it is not found rin v, it means vthat is rgreater than all elements in , so it can be vadded to rthe end of ,
  • And if there is an element rin ( *pindicated by in the code) that is greater than or equal to v, then use vto replace this element. In this way, on the one hand, if is *poriginally equal to v, then it has no effect; and if is *poriginally greater than v, then it will be updated to vafter , 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();
    }
};

Guess you like

Origin blog.csdn.net/Eric_1993/article/details/114380620