作业9 最长公共子序列

1.     问题

给定两个序列X,Y,求出X,Y的最长公共子序列

2.     解析

首先要引入一个定理来使得问题能够被简化。

在Zk是Xi和Yj的最长子序列的情况下(其中Xi表示长度为i的X序列)

(1)xi=yj,那么zk=xi=yj

(2)xi!=yj,zk!=xi,那么Zk是Xi-1和Yj的最长子序列

(3)xi!=yj,zk!=yj,那么Zk是Xi和Yj-1的最长公共子序列。

主要使用动态规划的方法来解决这个问题,主要引入两个二维数组来对中间过程进行存储。使用C[I,j]来表示Xi与Yj的最长公共子序列的长度。使用B[I,j]来存储在简化问题时的具体内容。通过引入C[I,j]来得到递推关系

3.     设计

得到最长字串长度

C[0,j] = C[I,0] = 0,1 <= I <= m,1<= j <= n

For I = 1 to m

       For j = 1 to n

              If(xi == yi)

              {

                     B[I,j] = BOTH //记录删除两个

                     C[I,j] = C[i-1,j-1]+1

              }

              Else

              {

                     If(C[I,j-1]>C[i-1,j])

                     {

                            C[I,j] = C[I,j-1];

                            B[I,j] = LEFT//删除Y

                     }

                     Else

                     {

                            C[I,j] = C[I-1,j];

                            B[I,j] = RIGHT//删除Y

                     }

              }

求出最长字串

Void find(B,I,j)

{

       If I == 0 or j == 0

              Return

       If B[I,j] = BOTH

              输出X[i]

              Find(B,i-1,j-1)

       Else if B[I,j] = LEFT

              Find(B,i-1,j)

       Else

              Find(B,I,j-1)

}

4.     分析

算法由两部分构成,求出最长公共字符串长度与求出最长字串。前一部分的时间复杂度远大于后一部分,因此忽略后一部分时间复杂度。而在前一部分中,最主要的部分是一个二重循环,因此时间复杂度为O(mn)。

5.     源码

https://github.com/fanchile/Algorithm

原文地址:https://www.cnblogs.com/Fanchile/p/12747728.html