非增长和非减少子序列

时间:2012-03-06 10:51:15

标签: string algorithm optimization data-structures

找到非递减子序列是众所周知的问题。 但是这个问题是发现最长的非递减子序列的一个轻微变体。在这个问题中,我们必须找到包含2个不相交序列的最长子序列的长度 1.非减少2.非增加。 例如在字符串“aabcazcczba”中最长的序列是aabczcczba。 aabczcczba由2个不相交的子序列aabcZccZBA组成。 (大写字母显示非递增序列)

我的算法是

length = 0
For i = 0 to length of given string S
  let s' = find the longest non-decreasing subsequence starting at position i
  let s" = find the longest non-increasing subsequence from S-s'.
  if (length of s' + length of s") > length
      length = (length of s' + length of s")
enter code here

但我不确定这是否能给出正确答案。你能在这个算法中找到一个错误吗?如果有错误也提示正确的算法。我还需要优化解决方案。我的算法大概需要o(n ^ 4)步。

2 个答案:

答案 0 :(得分:1)

您的解决方案绝对不正确。例如。 addddbc。最长的非递减序列是adddd,但是这永远不会给你一个不增加的序列。最佳解决方案是abc和dddd(或ab ddddc或ac ddddb)。

一种解决方案是使用动态编程。

F(i,x,a,b)= 1,如果x(x [:i])的前i个字母存在非递减和非递增的组合,则非递减部分的最后一个字母是a,非增加部分是b。如果相应的子序列为空,则这两个字母都等于NULL。

否则F(i,x,a,b)= 0。

F(i+1,x,x[i+1],b) = 1 if there exists a and b such that 
    a<=x[i+1] or a=NULL and F(i,x,a,b)=1. 0 otherwise.

F(i+1,x,a,x[i+1]) = 1 if there exists a and b such that
    b>=x[i+1] or b=NULL and F(i,x,a,b)=1. 0 otherwise. 

Initialize F(0,x,NULL,NULL)=1 and iterate from i=1..n

如您所见,您可以从F(i,x,a,b)得到F(i + 1,x,a,b)。复杂性:长度为线性,字母表大小为多项式。

答案 1 :(得分:0)

我得到了答案,这就是它的工作方式,而不是@ElKamina

维护一个27X27维度的表格。 27 =(1个空字符+ 26个(字母)) table [i] [j]表示子序列的长度,其非递减子序列具有最后一个字符'i',而非递增子序列具有最后一个字符'j'(第0个索引表示空字符,第k个索引表示字符'k')< / p>

表示i = 0到字符串S的长度

  //subsequence whose non decreasing subsequence's last character is smaller than S[i], find such a subsequence of maximum length. Now S[i] can be part of this subsequence's non-decreasing part.

  int lim = S[i] - 'a' + 1;
  for(int k=0; k<27; k++){
    if(lim == k) continue;
    int tmax = 0;
    for(int j=0; j<=lim; j++){
      if(table[k][j] > tmax) tmax = table[k][j];
    }
    if(k == 0 && tmax == 0) table[0][lim] = 1;
    else if (tmax != 0) table[k][lim] = tmax + 1;
  }
 //Simillarly for non-increasing subsequence

时间复杂度为o(lengthOf(S)* 27 * 27),空间复杂度为o(27 * 27)