繁体   English   中英

最长递增和递减子序列(自上而下记忆)

[英]Longest Increasing and Decreasing subsequence (Top-Down with memoization)

问题 - 给定一个长度为 N 的整数数组 A,找出最长子序列的长度,它首先增加然后减少。 输入:[1, 11, 2, 10, 4, 5, 2, 1]

输出:6

解释:[1 2 10 4 2 1] 是最长的子序列。

我写了一个自顶向下的方法。 我有五个参数 - 向量 A(包含序列)、起始索引(表示当前索引)、先前值、大(表示当前子序列中的最大值)和 map(m) STL。

对于回溯方法,我有两种情况-

  1. 元素被排除 - 在这种情况下,我们移动到下一个元素(开始+1)。 prev 和 large 保持不变。

  2. 包含元素 - 有两种情况

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

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

基本案例 -

  1. 如果当前索引不在数组中,即 start == end 然后返回 0。

  2. 如果序列减少然后增加则返回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);
}

不确定自上而下,但似乎我们可以使用经典的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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM