美文网首页
最长公共子序列和最长公共子串

最长公共子序列和最长公共子串

作者: 木的3次方 | 来源:发表于2017-03-17 15:12 被阅读0次

基本概念

首先,需要搞清楚这是两个不一样的问题,序列要求可以不是连续的,而子串要求必须是连续的。
下面我们将来介绍两个问题的解法,我们采用的方法是以空间换时间的动态规划的问题,对于动态规划,如何写出状态转移方程是问题求解的关键,还需要我们找出问题的起始解是什么。对于一些比较难得问题,我们无法直接应用动态规划,需要做一些变换(其中大部分是数学的思想)

最长公共子串

X=<x1,x2,x3......xn> ,Y=<y1,y2,y3......yn>
首先,我们先写出一个最简单的方法,状态转移方程为:
record[i][j] = record[i-1][j-1]+1
i,j表示以xi和yj结尾的最长公共子串,具体代码如下:

class Solution:
    def LongestCommonSubstring(self,text,query):
        record = [[0 for i in range(len(query)+1)] for j in range(len(text)+1)]
        record[0][0]=0
        res,index = 0,0
        for i in range(0,len(text)):
            for j in range(0,len(query)):
                if text[i]==query[j]:
                    record[i][j] = record[i-1][j-1]+1
                else:
                    record[i][j] = 0
                if res<record[i][j]:
                    res=record[i][j]
                    index=i
        return res,text[index-res+1:index+1]

if __name__ =="__main__":
    s = Solution()
    text,query = "acaccbabb","acbac"
    print s.LongestCommonSubstring(text,query)

上述揭发时间复杂度和空间复杂度均为为O(len(text)*len(query)),按常理,动态规划的空间复杂度是可以优化到1维数组的,需要逆序便利,为什么逆序,
具体如下:

class Solution:
    def LongestCommonSubstring(self,text,query):
        record = [0 for i in range(len(text)+1)]
        res,index = 0,0
        for i in range(len(query)):
            for j in range(len(text)-1,0,-1):
                if query[i]==text[j]:
                    record[j] = record[j-1]+1
                else:
                    record[j] = 0
                if res<record[j]:
                    res=record[j]
                    index=j
        return res,text[index-res+1:index+1]


if __name__ =="__main__":
    s = Solution()
    text,query = "acaccbabb","acbac"
    print s.LongestCommonSubstring(text,query)

最长公共子序列

相对于上一个问题,这个问题更难一点,首先还是要写出状态转移方程:

         if text[i-1]==query[j-1]:
              record[i][j]=record[i-1][j-1]+1
         else:                   
             record[i][j] = max(record[i-1][j],record[i][j-1])

代码如下:

class Solution:
    def LongestCommonSubSequeence(self,text,query):
        record = [[0 for j in range(len(query)+1)] for i in range(len(text)+1)]
        for i in range(len(text)+1):
            record[i][0] = 0
        for j in range(len(query)+1):
            record[0][j] = 0
        for i in range(1,len(text)+1):
            for j in range(1,len(query)+1):
                if text[i-1]==query[j-1]:
                    record[i][j]=record[i-1][j-1]+1
                else:
                    record[i][j] = max(record[i-1][j],record[i][j-1])
        return record[len(text)][len(query)]

if __name__ =="__main__":
    s = Solution()
    text,query = "acaccbabb","acbac"
    print s.LongestCommonSubSequeence(text,query)   

以上就是最长公共子串与最长公共子序列的解法

相关文章

  • 最长公共子序列和最长公共子串

    最长公共子序列和最长公共子串区别 最长公共子串(Longest CommonSubstring)和最长公共子序列(...

  • LCS问题

    LCS问题包括最长公共子序列和最长公共子串,其中,最长公共子串要求必须连续。 对于二者的求解方式 最长公共子序列:...

  • 算法(04)动态规划

    零钱问题 背包问题 最长公共子序列 最长公共子串 最长上升子序列 最大连续子序列和

  • 子串 子序列 总结

    最长公共子串 子串的要求比子序列严格,所以可以讨论子串的终点 最长公共子序列 DP解 递归+memo 最长公共回文...

  • 每天一道算法题18

    【最长公共子序列,子串】给定两个字符串上str1 和 str2, 求两个字符的最长公共子序列和最长公共子串。 最长...

  • 动态规划 最长公共子串

    核心思路和最长公共子序列一样 区别在于子串必须连续 可以先看我之前这篇文章最长公共子序列问题总结 最长公共子串同样...

  • 算法问题清单

    最大子序列和最长公共子序列最长公共子串大整数相乘/除/加数组最大乘积

  • 字符串算法

    最长公共前缀 最长回文串 最长回文子序列 最长公共子串 反转单词顺序列 反转字符串 字符串转数字 IP-int互转

  • 公共子序列问题

    最长公共子序列 最长上升子序列 最长公共上升子序列

  • 字符串的几个问题

    1.最长公共子序列2.最长公共子串3.最长回文串4.最长回文序列5.最长递增序列6.最长先增后减序列7.(最短)编...

网友评论

      本文标题:最长公共子序列和最长公共子串

      本文链接:https://www.haomeiwen.com/subject/dhssnttx.html