二維dp與最長(zhǎng)公共子串 2020-04-01

給定兩個(gè)字符串s1 和 s2,返回這兩個(gè)字符串的最長(zhǎng)公共子序列

這是關(guān)于2個(gè)字符串的dp模板問(wèn)題


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

最長(zhǎng)公共子序列的dptable

圖片源于leetcode
為了方便初始化dp的base case,可以看到在規(guī)模為len1 * len2的dp表上外擴(kuò)了一行+一列,表示字符串為''的情況

那么我們根據(jù)狀態(tài)轉(zhuǎn)移方程

if str1[i] == str2[j]:
    # 當(dāng)前相同元素納入最長(zhǎng)公共子序列
    dp[i][j] = dp[i-1][j-1] + str1[i]
else:
    # 取左元素或者上元素中長(zhǎng)度最長(zhǎng)的一個(gè)
    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二維數(shù)組的狀態(tài)轉(zhuǎn)移圖
class Solution:
    def longestCommonSubsequence(self, str1, str2) -> int:
        m, n = len(str1), len(str2)

        # 構(gòu)建 DP table 和 base case。注意,dp table的規(guī)模是(m+1)*(n+1),都外擴(kuò)了一層作為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):

                # 進(jìn)行狀態(tài)轉(zhuǎn)移
                # 如果兩個(gè)指針指向的元素相等
                if str1[i - 1] == str2[j - 1]:
                    # 找到一個(gè) lcs 中的字符
                    dp[i][j] = dp[i-1][j-1] + str1[i - 1]
                # 如果兩個(gè)指針指向的元素不等
                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]

        # 返回最長(zhǎng)公共子串長(zhǎng)度    
        return len(dp[-1][-1])
        # # 返回最長(zhǎng)公共子串
        # return dp[-1][-1]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容