动态规划:最长公共子串和最长公共子序列

最长公共子串

给定两个字符串,求出最长的相同的子串,例如给定子串asdfaswerasdfaswer,其中两个子串串中共有的最长子串就是asdfas这个字符串。
同样,这道题一看就是动态规划,我们首先列出状态转移方程,假设两个字符串分别以i,j为结尾的最长公共子串长度为dp[i][j],当A[i]==B[j]时,dp[i][j]=dp[i-1][j-1]+1,如果这两个字符不相等,也就是说以A[i],B[j]为结尾的这两个字符串就不是公共子串,此时dp[i][j]=0

asdfas
werasdfasw
s1 = input()
s2 = input()

n1 = len(s1)
n2 = len(s2)

dp = [[0 for _ in range(n2)] for _ in range(n1)]
max_len = 0
for i,x in enumerate(s1):
    for j,y in enumerate(s2):
        if x == y:
            if i == 0 or j == 0:
                dp[i][j] = 1
            else:
                dp[i][j] = dp[i-1][j-1] + 1
        if dp[i][j] > max_len:
            max_len = dp[i][j]
print(max_len)

最长公共子序列

公共子序列不需要连续,因此,即使两个字符串不相等,dp[i][j]也不会为0。当前两个字符不等,t1[i]!=t2[j]的话,那么长度最少也是dp[i-1][j-1],但这还不够,因为我们希望拿到之前的比较中尽可能大的长度。那么当前字符已经不相等的情况下,就应该把当前的字符也放入到之前的比较中,那么一定有dp[i][j-1]和dp[i-1][j]>=dp[i][j]。简单来说,dp[i][j]的值应该从dp[i-1][j-1],dp[i][j-1],dp[i-1][j]三者中取,但dp[i][j]≤另外两个,故比较另外两个,取较大的。

我们定义的状态表示f数组和text数组下标均是从1开始的,而题目给出的text数组下标是从0开始的,为了一 一对应,在判断text1和text2数组的最后一位是否相等时,往前错一位,即使用text1[i - 1]和text2[j - 1]来判断。

这里解释一下为什么f数组和text数组均定义成下标从1开始。原因是因为状态转移方程 f[i][j] = max(f[i - 1][j],f[i][j - 1]), 当我们的f数组定义成下标从1开始以后,我们就可以在代码中不用对下标越界问题做出额外判断。其实我们也可以发现一个问题,就是题目给定的原数组,比如text数组,如果下标从1开始的话,状态表示会更加的清晰,推导状态转移方程的过程也会更加好理解。

class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        m, n = len(text1), len(text2)
        dp = [[0] * (n + 1) for _ in range(m + 1)]
        
        for i in range(1, m + 1):
            for j in range(1, n + 1):
                if text1[i - 1] == text2[j - 1]:
                    dp[i][j] = dp[i - 1][j - 1] + 1
                else:
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
        
        return dp[m][n]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值