美文网首页
二维dp与最长公共子串 2020-04-01

二维dp与最长公共子串 2020-04-01

作者: 9_SooHyun | 来源:发表于2020-04-01 14:36 被阅读0次

给定两个字符串s1 和 s2,返回这两个字符串的最长公共子序列

这是关于2个字符串的dp模板问题


s1 = 'ace'
s2 = 'babcde'为例
dptable如下

最长公共子序列的dptable
图片源于leetcode
为了方便初始化dp的base case,可以看到在规模为len1 * len2的dp表上外扩了一行+一列,表示字符串为''的情况

那么我们根据状态转移方程

if str1[i] == str2[j]:
    # 当前相同元素纳入最长公共子序列
    dp[i][j] = dp[i-1][j-1] + str1[i]
else:
    # 取左元素或者上元素中长度最长的一个
    if len(dp[i-1][j]) > len(dp[i][j-1]):
        dp[i][j] = dp[i-1][j]
    else:
        dp[i][j] = dp[i][j-1] 

如图所示:


dp二维数组的状态转移图
class Solution:
    def longestCommonSubsequence(self, str1, str2) -> int:
        m, n = len(str1), len(str2)

        # 构建 DP table 和 base case。注意,dp table的规模是(m+1)*(n+1),都外扩了一层作为base case
        dp = [['' for i in range(n+1)] for j in range(m + 1)]
        
        # 开始填dp表
        for i in range(1, m + 1):
            for j in range(1, n + 1):

                # 进行状态转移
                # 如果两个指针指向的元素相等
                if str1[i - 1] == str2[j - 1]:
                    # 找到一个 lcs 中的字符
                    dp[i][j] = dp[i-1][j-1] + str1[i - 1]
                # 如果两个指针指向的元素不等
                else:
                    if len(dp[i-1][j]) > len(dp[i][j-1]):
                        dp[i][j] = dp[i-1][j]
                    else:
                        dp[i][j] = dp[i][j-1]

        # 返回最长公共子串长度    
        return len(dp[-1][-1])
        # # 返回最长公共子串
        # return dp[-1][-1]

相关文章

网友评论

      本文标题:二维dp与最长公共子串 2020-04-01

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