Description

Given an integer array nums, return the length of the longest strictly increasing

subsequence

.

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: Can you come up with an algorithm that runs in O(n log(n)) time complexity?

Code

DP

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        vector<int> dp(n, 1);
        for(int i = 1; i < n; i++) {
            for(int j = 0; j < i; j++) {
                if(nums[i] > nums[j])
                    dp[i] = max(dp[i], dp[j] + 1);
            }
        }
 
        return *max_element(dp.begin(), dp.end());
    }
};
 

Greedy with binary search O(n \log n)

res 為 increasing sequence。

對於 num[i] 來說,有兩種情形,一種是它比 res 的尾端大,那就直接 insert。

第二種情形是它比 res 的尾端小,就必須找到 res 中比它大的最小元素,將之取代。

取代比之大的最小元素及為 greedy choice,因為 num[i] 比較小,因此取代了之後所會造成的可能的 increasing sequence 只會更長不會更短。

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> t;
        for(auto n: nums) {
            if(t.empty() || n > t.back()) 
                t.push_back(n);
            else {
                int l = 0, r = t.size() - 1;
                while(l < r) {
                    int mid = (l + r) / 2;
                    if(t[mid] < n) l = mid + 1;
                    else r = mid;
                }
                t[l] = n;
            }
        }
        return t.size();
    }
};

其中 binary search 可以使用 std::lower_bound

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int> res;
        for(auto num: nums) {
            if(res.empty() || res.back() < num) {
                res.emplace_back(num);
            } else {
                auto it = lower_bound(res.begin(), res.end(), num);
                *it = num;
            }
        }
        return res.size();
    }
};
 
 

Source