最长递增子序列问题代码

问题描述

问题链接

[链接] 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

没有弄错它。

解决方法

#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,Input2 { 10,12,Input3 { 10,15,Input4 { 10,13,Input5 { 10,17,Input6 { 10,10,Input7 { 10,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;
}
,

每次访问新索引(即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;
    }
};
,

使用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 / {{ 3}}分析memory1