【问题标题】:Longest Increasing Subsequence problem (leetcode)最长递增子序列问题(leetcode)
【发布时间】:2020-08-23 17:08:54
【问题描述】:

问题链接:

[链接]https://leetcode.com/problems/longest-increasing-subsequence/

class Solution {
public:
int lengthOfLIS(vector& nums)
{
int n=nums.size();
if (n==0)
return 0;

    int list[n];
    for(int i=0;i<n;i++)
        list[i]=0;
    
    list[0]=1;
    for(int i=1;i<n;i++)
    {
        for(int j=i-1;j>=0;j--)
        {
            if(nums[j]<nums[i])
                list[i]=max(list[i],1+list[j]);
        }
    }
    int ans=1;
    for(int i=0;i<n;i++)
        ans=max(ans,list[i]);
    return ans;
}
};

输入:[10,9,2,5,3,7,101,18]

输出来了:3

预期输出:4

没有弄错地方。

【问题讨论】:

  • 你调试了吗?您是否在纸上一步一步地完成了它?从理论上讲,这应该只需要时间,而不是知识......
  • @AsteroidsWithWings 我做了所有这些我得到 4 作为我的 ans 但编译器说 3
  • 这个问题很愚蠢,因为如果你正在寻找一个子序列,那么它本质上应该是一个连续的子序列。反正我看不懂这个说法:list[i]=max(list[i],1+list[j]);您应该通过将所有值填充为 1 来将数组初始化为 1。遗漏的细微之处在于,对于每个子序列,您希望将每个值测试为子序列中的最小值。我在下面提交了一个可行的解决方案以及一些测试用例。

标签: c++ dynamic-programming


【解决方案1】:
#include <vector>
#include <iostream>
#include <algorithm>
#include <sstream>

class Solution
{
public:
  int lengthOfLIS(std::vector<int> &);
  int max(int, int);
  std::string print(std::vector<int> const &);
};

int Solution::max(int a, int b)
{
  return a < b ? b : a;
}

std::string Solution::print(std::vector<int> const &input)
{
  std::stringstream ss;
    for (int i = 0; i < input.size(); i++)
        ss << input.at(i) << ' ';

  return ss.str();
}

int Solution::lengthOfLIS(std::vector<int> &nums)
{
  int n = nums.size();
  
  if (n == 0)
    return 0;

  int list[n];
  std::fill_n(list, n, 1);
  //list[0] = 1;

  for (int i = 1; i < n; i++)
  {
    int min_val = nums[i];

    for (int j = i - 1; j > -1; j--)
    {
      if (nums[j] < nums[i] && nums[j] < min_val)
      {
        list[i]++;
        min_val = nums[j];
      }
    }
  }

  int ans = 1;

  for(int i = 0; i < n; i++)
    ans = max(ans, list[i]);

  return ans;
}

int main()
{
  std::vector<int> Input0 { 10, 9, 2, 5, 3, 7, 101, 18 },
    Input1 { 10, 19, 2, 5, 3, 7, 101, 18 },
    Input2 { 10, 9, 12, 5, 3, 7, 101, 18 },
    Input3 { 10, 9, 2, 15, 3, 7, 101, 18 },
    Input4 { 10, 9, 2, 5, 13, 7, 101, 18 },
    Input5 { 10, 9, 2, 5, 3, 17, 101, 18 },
    Input6 { 10, 9, 2, 5, 13, 7, 10, 18 },
    Input7 { 10, 9, 2, 5, 13, 7, 101, 180 };
  Solution solution;
  std::cout << solution.print(Input0) << "\t|\t" << solution.lengthOfLIS(Input0) << std::endl;
  std::cout << solution.print(Input1) << "\t|\t" << solution.lengthOfLIS(Input1) << std::endl;
  std::cout << solution.print(Input2) << "\t|\t" << solution.lengthOfLIS(Input2) << std::endl;
  std::cout << solution.print(Input3) << "\t|\t" << solution.lengthOfLIS(Input3) << std::endl;
  std::cout << solution.print(Input4) << "\t|\t" << solution.lengthOfLIS(Input4) << std::endl;
  std::cout << solution.print(Input5) << "\t|\t" << solution.lengthOfLIS(Input5) << std::endl;
  std::cout << solution.print(Input6) << "\t|\t" << solution.lengthOfLIS(Input6) << std::endl;
  std::cout << solution.print(Input7) << "\t|\t" << solution.lengthOfLIS(Input7) << std::endl;
  return 0;
}

【讨论】:

  • 谢谢哥们,但是我想再说一遍,我只是想在我的解决方案中找出错误。
  • 这个测试 if(nums[j]
【解决方案2】:

您的代码中只有一个小错误,每次您访问新索引时(即在 i 的每次迭代中),可以为索引找到的最长递增子序列就是该元素本身。

因此,对于每次迭代,您最初应该设置 list[i] = 1

或者,您也可以将列表数组中的每个元素初始化为 1。

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n=nums.size();
        if (n==0)
            return 0;

        int list[n];
        for(int i=0;i<n;i++)
            list[i]=0;

        list[0]=1;
        for(int i=1;i<n;i++) {
            list[i] = 1;
            for(int j=i-1;j>=0;j--) {
                if(nums[j]<nums[i])
                list[i]=max(list[i],1+list[j]);
            }
        }
        int ans=1;
        
        for(int i=0;i<n;i++)
            ans=max(ans,list[i]);
        return ans;
    }
};

【讨论】:

    【解决方案3】:

    使用std::lower_bound,通过:

    #include <cstdint>
    #include <vector>
    #include <algorithm>
    
    static const struct Solution {
        static const int lengthOfLIS(
            const std::vector<int> &nums
        ) {
            std::vector<int> longest;
    
            for (std::size_t index = 0; index < nums.size(); index++) {
                const auto iter = std::lower_bound(longest.begin(), longest.end(), nums[index]);
    
                if (iter == longest.end()) {
                    longest.emplace_back(nums[index]);
    
                } else {
                    *iter = nums[index];
                }
            }
    
            return longest.size();
        }
    };
    

    参考文献

    • 有关更多详细信息,请参阅Discussion Board,您可以在其中找到大量解释清楚且公认的解决方案,其中包含各种languages,包括低复杂度算法和渐近runtime/memory 分析@ 987654325@, 2.

    【讨论】:

    • 什么是static const struct?为什么函数应该返回const int
    • 我不想要朋友,我只需要检查我的代码并检查哪里出错
    猜你喜欢
    • 2013-07-03
    • 2017-01-07
    • 1970-01-01
    • 2020-04-15
    • 1970-01-01
    • 2018-11-01
    相关资源
    最近更新 更多