最长的子序列线性时间

时间:2013-12-06 10:06:47

标签: algorithm recursion dynamic-programming

我正在阅读增长最长的子序列问题: 给定数组A = {a_1,a_2,...,a_n},找到最长增长子序列的长度(不一定是连续的) 我想到了一个递归解决方案,其中memoization(或DP)具有复杂度= O(n * max(a_i))。 所以基本上是n *范围的a_i。 我找到的所有解决方案都是O(n ^ 2)或O(nlogn),这个解决方案在逻辑上有什么问题吗?

这是代码: 不失一般性,假设所有a_i的> 0

#include <iostream>
using namespace std;
int count = 0;
int lis(int A[], int loc, int length, int ** table, int max_so_far=0){
count++;
    if (loc == length)
  return 0;

    if (table[loc][max_so_far] != -1)
      return table[loc][max_so_far];

int val1 = 0, val2 = 0;
val1 = lis(A, loc+1, length, table, max_so_far);
if (max_so_far < A[loc])
    val2 = 1 + lis(A, loc+1, length, table, A[loc]);
    table[loc][max_so_far] = max(val1,val2);
return max(val1,val2); 
}

int main(){
int A[]={10, 11, 12, 9, 8, 7, 5, 6};
     int A[]={1,3,2,5,1,3,2,5,1,3,2,5,1,3,2,5,1,3,2,5,1,3,2,5,1,3,2,5, 1,3,2,5, 1,3,2,5, 1,3,2,5, 1,3,2,5, 1,3,2,5};
    int ** table;
int n = 49;
    int range = 6;
table = new int*[n];
    for (int i =0;i<n;i++){
      table[i] = new int[range];
      for(int j=0;j<range;j++)
       table[i][j] = -1;
}
    count = 0;
    cout<<lis(A, 0, n, table, 0)<<endl;
cout<<"Number of calls made: "<<count<<endl;
    return 0;
}

2 个答案:

答案 0 :(得分:0)

这只是编写标准O(n ^ 2)算法的一种复杂且空间效率低的方法。

答案 1 :(得分:0)

我认为你接近没有任何问题。正如你所说,复杂性是O(n * | A |)其中| A |是唯一元素的数量。在最坏的情况下,| A | = n。