当前位置: 首页 > 知识库问答 >
问题:

最长递增子序列。为什么自上而下的代码不起作用?

廉博赡
2023-03-14

Q、 给定整数数组nums,返回最长严格递增子序列的长度。

子序列是一个序列,可以通过删除一些元素或不删除任何元素而从数组中派生,而不改变其余元素的顺序。例如,[3,6,2,7]是数组[0,3,1,6,2,2,7]的子序列。

示例1:

输入:nums=[10,9,2,5,3,7,101,18]
输出:4

说明:最长的递增子序列为[2,3,7101],因此长度为4。

答案:

我的递归代码工作正常,但自顶向下的DP代码不工作。即使我只是将正确答案存储在dp向量中,然后再次使用它们。

递归代码

int lengthOfLIS(vector<int>& arr, int i=0, int prev= INT_MIN){
        //........... base case............
        if(i==arr.size()) return 0;
        //........... recursive case...........
        // take if it is grater than prev
        int X = INT_MIN;
        if(arr[i] > prev)
            X = 1 + lengthOfLIS(arr, i+1, arr[i]);
        // ignore
        int Y = lengthOfLIS(arr, i+1, prev);
    
        return max(X, Y);
    }


TopDown DP code:- 

int sol(vector<int> arr, vector<int>& dp, int i=0, int prev= INT_MIN){
        //........... base case............
        if(i==arr.size()) return dp[i]=0;
        if(dp[i]!=-1) return dp[i];
        //........... recursive case...........
        // take if it is grater than prev
        int X = INT_MIN;
        if(arr[i] > prev)
            X = 1 + sol(arr, dp, i+1, arr[i]);
        // ignore
        int Y = sol(arr, dp, i+1, prev);
    
        return dp[i] = max(X, Y);
    }

共有1个答案

丰胤运
2023-03-14

基本上,您希望使用dp进行记忆。在这种情况下,我建议使用2d向量进行记忆。

因此,最终解决方案将是:

int lengthOfLIS(vector& nums){

int n=nums.size();

vector<vector<int>> dp(n,vector<int>(n+1,-1));
 
return sol(nums,0,n,-1,dp);

}

int sol(vector<int>& nums,int i,int n,int prev,vector<vector<int>>& dp){

if(i==n){
    return 0;
} 

if(dp[i][prev+1]!=-1){
    
    return dp[i][prev+1];
    
}

int X=0;int Y=0;
      
if(prev==-1 or nums[i]>nums[prev]){
    
    X=1+sol(nums,i+1,n,i,dp);
    
}

Y=sol(nums,i+1,n,prev,dp);
   
dp[i][prev+1]=max(X,Y);

return dp[i][prev+1];

}   
};

这个概念和你的一样,我刚刚使用了2d向量dp。

 类似资料:
  • 在最多一个序列存在重复的情况下,可以将最长公共子序列问题转化为最长递增子序列问题。减少问题的过程说明在这里: 假设您有以下序列: 然后,创建一个整数序列S3,其中您必须将S2的每个元素的位置放在S1中(如果元素在S1中不存在,那么忽略那个元素)。在本例中: 这种方法是如何工作的?为什么这种约简解决了寻找最长公共子序列的问题?

  • 我在阅读了允许K个异常的最长递增子序列后创建了这个线程。我意识到提问的人并没有真正理解这个问题,因为他指的是一个链接,该链接解决了“允许一次更改的最长递增子数组”问题。所以他得到的答案实际上与李的问题无关。 假设给定一个长度为N的数组A。查找允许K个异常的最长递增子序列。 示例:N=9,K=1 A=[3,9,4,5,8,6,1,3,7] 答案:7 说明: 最长递增子序列为:3,4,5,8(或6),

  • 最长增子序列是我们熟知的问题,我用耐心算法给出了一个解决方案。 我曾想过先用我的算法,然后找到长度为N的第一个序列,但不知道该怎么做。 那么,如何从随机整数序列中找到第一个最长的递增子序列呢? 我的代码段: 我的代码返回:1 2 8 第一个序列是:3 6 8 另一个例子: 我的代码正确返回:1 2 3 基本上,只要第一个最长序列与最佳最长序列相同,我的代码就能工作。但是当你有一堆相同长度的最长序列

  • 问题-给定一个长度为N的整数数组,求最长子序列的长度,该序列先增加后减少。投入:[1,11,2,10,4,5,2,1] 产出:6 说明:[1,210,4,21]是最长的子序列。 我写了一个自上而下的方法。我有五个参数--vector A(包含序列)、start index(表示当前索引)、previer value、large(表示当前子序列中的最大值)和map(m)stl。 对于回溯方法,我有两

  • 假设我们有一些不相交的递减序列: 我选择一些递减序列(例如按顺序,,,,的5个递减序列)并将它们级联(结果序列。 现在我想求S中最长递增子序列的长度,在上面的示例中:-> 预期时间复杂度小于O(S)。

  • 我想了两个小时,为什么这段代码不能产生预期的结果。如果我输入3个整数,比如3、4和5,它应该给出所有27个可能的和(假设数字可以是正的、负的或零) 因此,它应该产生以下内容: -3-4-5=-12 -3-4 0 = -7 -4-4 5=3 等等