Leetcode300. 最长递增子序列

Every day a Leetcode

题目来源:300. 最长递增子序列

解法1:递归

枚举 nums[i] 作为最长递增子序列的末尾元素,那么需要枚举 nums[j] 作为最长递增子序列的倒数第二个元素,其中 j<i 并且 nums[j]<nums[i]。

问题转化为更小的子问题:求以 nums[j] 为末尾的最长递增子序列,可以用递归来求解

代码:

// 递归

class Solution
{
   
public:
    int lengthOfLIS(vector<int> &nums)
    {
   
        // 特判
        if (nums.size() == 1)
            return 1;

        int n = nums.size();

        function<int(int)> dfs = [&](int i)
        {
   
            int res = 0;
            for (int j = 0; j < i; j++)
                if (nums[j] < nums[i])
                    res = max(res, dfs(j));
            return res + 1;
        };

        int ans = 0;
        for (int i = 0; i < n; i++)
            ans = max(ans, dfs(i));
        return ans;
    }
};

结果:

在这里插入图片描述

复杂度分析:

时间复杂度:O(n2),其中 n 是数组 nums 的元素个数。

空间复杂度:O(n),其中 n 是数组 nums 的元素个数。

解法2:动态规划

代码:

// 动态规划

class Solution
{
   
public:
    int lengthOfLIS(vector<int> &nums)
    {
   
        // 特判
        if (nums.size() == 1)
            return 1;

        int n = nums.size(), maxLength = 0;
        // 状态数组,并初始化
        vector<int> dp(n, 1);
        // 状态转移
        for (int i = 0; i < n; i++)
            for (int j = 0; j < i; j++)
            {
   
                if (nums[j] < nums[i])
                    dp[i] = max(dp[i], dp[j] + 1); // 状态转移方程
                maxLength = max(maxLength, dp[i]);
            }
        return maxLength;
    }
};

结果:

在这里插入图片描述

复杂度分析:

时间复杂度:O(n2),其中 n 是数组 nums 的元素个数。

空间复杂度:O(n),其中 n 是数组 nums 的元素个数。

解法3:贪心 + 二分查找

遍历数组 nums:

在这里插入图片描述

最后 g 就是最长递增子序列。

在这里插入图片描述

对应到代码上,就是把 lower_bound 改成 upper_bound。

代码:

// 贪心 + 二分查找

class Solution
{
   
public:
    int lengthOfLIS(vector<int> &nums)
    {
   
        // 特判
        if (nums.size() == 1)
            return 1;

        int n = nums.size();
        vector<int> g;
        for (int i = 0; i < n; i++)
        {
   
            int j = lower_bound(g.begin(), g.end(), nums[i]) - g.begin();
            if (j == g.size())
                g.push_back(nums[i]);
            else
                g[j] = nums[i];
        }
        return g.size();
    }
};

结果:

在这里插入图片描述

复杂度分析:

时间复杂度:O(nlogn),其中 n 是数组 nums 的元素个数。

空间复杂度:O(n),其中 n 是数组 nums 的元素个数。

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-01-27 15:44:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-27 15:44:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-27 15:44:04       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-27 15:44:04       20 阅读

热门阅读

  1. 万年历(方法版)

    2024-01-27 15:44:04       39 阅读
  2. 速盾:服务器接入CDN后上传图片失败的解决方案

    2024-01-27 15:44:04       24 阅读
  3. Git推送大量内容导致http 413错误

    2024-01-27 15:44:04       40 阅读
  4. 方法的重载

    2024-01-27 15:44:04       29 阅读
  5. git从clone到pr的全流程

    2024-01-27 15:44:04       36 阅读