最长公共子序列(LCS) 最长公共子串

最长公共子序列(LCS):最长公共子序列问题是在一组序列(通常2个)中找到最长公共子序列(注意:不同于子串,LCS不需要是连续的子串,
但是各个元素之间的相对顺序不能改变)

但是最长公共子序列和最长公共子串的问题都类似于爬楼梯问题,对于不要求各元素连续的LCS问题来说:当求两字符串[0,i]和[0,j]这两个区间
中的最长公共子序列dp[i][j]有2种来源:
(1)当字符串1的第i个元素和字符串2的第j个元素相同的时候:dp[i][j] = dp[i-1][j-1] + 1 
(2) 如果不同的话,在[0,i]和[0,j]这两段区间中的最长公共子序列肯定不等于dp[i-1][j-1] + 1了,它应该由两种可能,可能等于dp[i-1][j] 或者 dp[i][j-1],又因为题目要最大值所以就对两个可能的来源取最大值。

最长公共子串问题:
和最长公共子序列的思路大体类似,区别在于最长公共子串问题的dp[i][j]只有一个可能来源,因为最长公共子序列需要是连续的,对dp[i][j]来说如果第i个元素和j元素不同的话,即使dp[i-1][j-1]不为0,dp[i][j] 也是为 0,因为需要连续,
如果第i个元素和j元素相同的话,dp[i][j] = dp[i-1][j-1] + 1
LintCode 上有最长公共子序列(不要求连续)的题目:

https://www.lintcode.com/problem/longest-common-subsequence/description

class Solution:
    """
    @param A: A string
    @param B: A string
    @return: The length of longest common subsequence of A and B
    """
    def longestCommonSubsequence(self, A, B):
        # write your code here
        m = len(A)
        n = len(B)
        dp = [[0 for i in range(n + 1)] for j in range(m + 1)]
        for i in range(m + 1):
            for j in range(n + 1):
                if i == 0 or j == 0:
                    dp[i][j] = 0
                    continue
                if A[i - 1] == B[j - 1]:
                    dp[i][j] = dp[i-1][j-1] + 1
                else:
                    dp[i][j] = max(dp[i][j-1],dp[i-1][j]) # A[i - 1] != B[j - 1] 所以dp[i][j] 取 max(dp[i][j-1],dp[i-1][j])  不是 max(dp[i][j-1],dp[i-1][j]) + 1 因为最长公共子序列的长度没有增加
        return dp[m][n]
LintCode 上的最长公共子串(要求连续)问题:

?  https://www.lintcode.com/problem/longest-common-substring/description

class Solution:
    """
    @param A: A string
    @param B: A string
    @return: the length of the longest common substring.
    """
    def longestCommonSubstring(self, A, B):
        # write your code here
        m = len(A)
        n = len(B)
        if m == 0 or n == 0:
            return 0
        res = 0
        dp = [[0 for i in range(n + 1)] for j in range(m + 1)]
        for i in range(1,m + 1):
            for j in range(1,n + 1):
                # if i == 0 or j == 0:
                #     continue
                if A[i - 1] == B[j - 1]:
                    dp[i][j] = dp[i-1][j-1] + 1
                    res = max(res,dp[i][j])
        return res
# 暴力做法:
class Solution:
    """
    @param A: A string
    @param B: A string
    @return: the length of the longest common substring.
    """
    def longestCommonSubstring(self, A, B):
        # write your code here
        lena = len(A)
        lenb = len(B)
        res = 0
        if lena < lenb:
            C = B
            B = A
            A = C
            lena = lenb
            lenb = len(A)
        for i in range(lena):
            for j in range(i,lena):
                if A[i:j+1] in B:
                    res = max(res,j - i + 1)
        return res

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值