寻找子序列

来源:互联网 发布:用java 编写一个计算器 编辑:程序博客网 时间:2024/05/16 05:17

1.最长不降子序列:

给出数组A[n],在其中找到最长的子序列subA,要求subA中每一项都大于等于前一项。

O(n2):f[n]表示以第n个数为结尾的不降子序列的长度。n从1开始。f[0] = 0,A[0] = -10000000000,递推公式:f[1] = 1.  f[2]= 2  ( A[2] >= A[1] )   f[2] = 1 (A[2] < A[1])

一般的,有f[i] = max{f[j]} + 1, A[j] <= A[i]且j<i  1<=i<=n。

max{f[i]} 1<=i<=n即最长不降子序列的长度,可增加数组保存子序列


2.最长公共子序列:

O(m*n)

给出串A[n],B[m],找最长公共子串subAB。

f[i][j]表示A取到前i字符,B取到前j字符时最长公共子串的长度。

f[i][j] = f[i-1][j-1] (A[i] == B[j])

f[i][j] = max{f[i][j-1],f[i-1][j]}  (A[i] != B[j])

f[n][m]为最长公共子串长度

 

3.最大子串和

O(n)

给出数组A,求A的和最大的连续子串。

for (int i = 0; i < n ; i++)

{

   cur += A[i];

   if (cur <= 0)

      cur = 0;

   if (cur >= maxx)

     maxx = cur;

}

 

4.最长公共子串 (连续)

给出两串s1 ,s2.求其最长公共子串。

LCS  (DP)

O(m*n)

构造二维矩阵,对应位置字符相同,置1,否则为0.

找所有对角线连续1最大的个数。

优化:只记录矩阵中的当前行 每次记录当前行中最大的值。

 

GST(后缀树)

 将s1 s2合并为s1#s2$,压入后缀树,找到最深的非叶子节点,该节点的叶子节点既有#又有$。该节点表示的串即为所求。

可扩展为多个串的最长公共子串。

 

原创粉丝点击