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

最长递增和递减子序列(自顶向下带记忆)

冉昊
2023-03-14

问题-给定一个长度为N的整数数组,求最长子序列的长度,该序列先增加后减少。投入:[1,11,2,10,4,5,2,1]

产出:6

说明:[1,210,4,21]是最长的子序列。

我写了一个自上而下的方法。我有五个参数--vector A(包含序列)、start index(表示当前索引)、previer value、large(表示当前子序列中的最大值)和map(m)stl。

对于回溯方法,我有两个案例-

>

  • 元素被排除-在本例中,我们移到下一个元素(start+1)。prev和large保持不变。

    元素-有两种情况

    a.如果当前值(A[start])大于prev,并且prev==大,那么这就是递增序列的情况。然后方程变为1+LS(start+1,A[start],A[start]),即prev变为当前元素(A[start]),最大元素也变为[start]。

    b.如果电流值(A[start])小于prev,而电流(A[start])<大,则这是递减序列的情况。然后方程变为1+LS(start+1,a[start],lage),即prev变为当前元素(a[start]),最大元素保持不变,即lage。

    基本案例-

    >

  • 如果当前索引不在数组中,即start==end,则返回0。

    如果序列先递减后递增,则返回0。即,如果(当前>上一个和上一个<最大值),则返回0。

    这不是一个优化的方法,因为map.find()本身就是一个代价高昂的操作。有人可以建议最优化的自上而下的回忆录方法。

    int LS(const vector<int> &A, int start, int end, int prev, int large, map<string, int>&m){
    
        if(start == end){return 0;}
        if(A[start] > prev && prev < large){
            return 0;
        }
    
        string key = to_string(start) + '|' + to_string(prev) + '|' + to_string(large);
    
        if(m.find(key) == m.end()){
            int excl = LS(A, start+1, end, prev, large, m);
            int incl = 0;
            if(((A[start] > prev)&&(prev==large))){
                incl = 1 + LS(A, start+1, end, A[start],A[start], m); 
            }else if(((A[start]<prev)&&(A[start]<large))){
                incl = 1+ LS(A, start+1, end, A[start], large, m);
            }  
    
            m[key] = max(incl, excl);
        }
    
        return m[key];
    }
    
    int Solution::longestSubsequenceLength(const vector<int> &A) {
            map<string, int>m;
            return LS(A, 0, A.size(), INT_MIN, INT_MIN, m);
    }
    
  • 共有1个答案

    钮长恨
    2023-03-14

    不确定自上而下,但似乎我们可以使用经典的LIS算法来从“两边”接近每个元素。下面是一个示例,当我们从两个方向迭代时,每个元素分别作为最右边和最左边。我们可以看到长度为6的有效序列的三个实例:

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

    • 我在阅读了允许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 基本上,只要第一个最长序列与最佳最长序列相同,我的代码就能工作。但是当你有一堆相同长度的最长序列

    • 我试图解决Leetcode上最长的回文子串。我知道这个问题的解决方案,比如围绕中心展开或动态编程自下而上的方法。出于纯粹的教育目的,我想以自上而下的递归方式解决这个问题。我试图找到类似于这里或这里描述的解决方案。(问题略有不同)。我有这个功能: 它接受搜索的字符串开始和结束位置。返回的元组是最长palindrom的开始和结束。我试图分成以下情况: 如果s[i]==s[j],则调查最长(s,i 1,

    • 所以我用动态编程做了一个简单的python代码来解决最大递增子序列的问题。问题如下: 给定一个数组 arr 的 N 个正整数。求出给定数组的最大和递增子序列的总和。 输入:输入的第一行包含一个整数 T,表示测试用例的数量。每个测试用例的第一行是 N(数组的大小)。每个测试用例的第二行包含数组元素。 输出:对于每个测试用例,在新行中打印所需的答案。 在我的解决方案中,我正在计算一个名为“总和”的列表

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