300. Longest Increasing Subsequence**

300. Longest Increasing Subsequence**

https://leetcode.com/problems/longest-increasing-subsequence/

题目描述

Given an unsorted array of integers, find the length of longest increasing subsequence.

Example:

Input: [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. 

Note:

  • There may be more than one LIS combination, it is only necessary for you to return the length.
  • Your algorithm should run in O ( n 2 ) O(n^2) complexity.

Follow up: Could you improve it to O ( n l o g n ) O(n log n) time complexity?

C++ 实现 1

动态规划.

使用 f[i] 表示以 nums[i] 结尾的 LIS. 那么:

f[i] = max(nums[i] > nums[k] ? (f[k] + 1) : 1, f[i]); 其中 k = 1, 2, ..., i - 1

上面意思就是说, nums[i] 要和它之前的所有数字 nums[k] 进行比较, 从而找到 LIS.

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        if (nums.empty()) return 0;
        int res = 1;
        vector<int> f(nums.size(), 1);
        for (int i = 1; i < nums.size(); ++ i) {
            for (int j = i - 1; j >= 0; -- j) {
                auto tmp = nums[i] > nums[j] ? f[j] + 1 : 1;
                f[i] = std::max(f[i], tmp);
            }
            res = std::max(f[i], res);
        }
        return res;
    }
};

C++ 实现 2

思路和 C++ 实现 1 一致, 写法稍不同.

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

C++ 实现 3

Follow Up 中要求的 O ( N log N ) O(N \log N) 方法. 相当于是将 LIS 给找出来了, 使用 res 存储 LIS, 对于放在 LIS 中的每个元素, 如果我们访问到 nums[i] 时, 发现 res 中有比 nums[i] 更大(或等于) 的元素, 就替换该元素. 这里不用 upper_bound, 否则最后出来的 LIS 就会有重复元素, 不符合 LIS 的定义.

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        if (nums.empty()) return 0;
        vector<int> res;
        int n = nums.size();
        for (int i = 0; i < n; ++i) {
            if (res.empty() || nums[i] > res.back())
                res.push_back(nums[i]);
            else if (nums[i] < res.back()) {
                // lower_bound 是 res 中第一个大于或等于 nums[i] 的元素
                auto iter = std::lower_bound(res.begin(), res.end(), nums[i]);
                *iter = nums[i];
            }
        }
        return res.size();
    }
};

发布了497 篇原创文章 · 获赞 9 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Eric_1993/article/details/105063631