• 作业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

  • 相关阅读:
    PHP面试系列之Linux(一) ----- Linux基础
    Redis入门(一)---安装
    获取主机ip地址
    Ubuntu安装Apache
    Ubuntu安装MySQL/MariaDB
    Ubuntu安装PHP7
    shell一次性执行多条命令
    将宿主主机上的目录挂载到Docker中
    bind 仿造 重写bind
    echars 饼状图 轮循 水平翻转
  • 原文地址:https://www.cnblogs.com/Fanchile/p/12747728.html
Copyright © 2020-2023  润新知