算法學習-LCS 最長公共子序列

算法學習-LCS 最長公共子序列

0x01 摘要

LCS
全稱Longest Common Subsequence,即最長公共子序列問題。本文實現代碼採用Python

0x02 思路

首先我們想到的是用遞歸的方式,此方法思考起來比較簡單,但缺點是會有重複計算,性能較低。

該問題其實就是父問題和子問題的關係,可以考慮採用動態規劃算法。

記狀態轉移二維數組dp[i][j]表示從 字符串a中下標 0到i-1 和 字符串b中0到j-1 的最長公共子序列。

經過推導可以得出狀態轉移方程如下:

# 當a[i-1] == b[j-1]時
dp[i][j] = dp[i-1][j-1] + a[i-1]

# 當len(dp[i-1][j]) > len(dp[i][j-1])
dp[i][j] = dp[i-1][j]

# 否則
dp[i][j] = dp[i][j-1]

從1到len+1遍歷a、b字符串,最終得到的 dp[len_a][len_b]便是最終結果,代表字符串a和字符串b的最長公共子序列。

0x03 動態規劃實現代碼

python實現代碼如下:

# -*- coding:utf-8 -*-

# 動態規劃思想求解最長公共子序列
def lcs_dynamic_planning(a, b):
    len_a = len(a)
    len_b = len(b)
    # 創建狀態二維數組,注意這裏爲了程序求解需要,長度是len+1
    dp = [['' for i in range(len_b+1)] for j in range(len_a+1)]

    for i in range(1, len_a + 1):
        for j in range(1, len_b + 1):
            if a[i-1] == b[j-1]:
                dp[i][j] = dp[i-1][j-1] + a[i-1]
            else:
                lcs_1 = dp[i-1][j]
                lcs_2 = dp[i][j-1]
                if len(lcs_1) > len(lcs_2):
                    dp[i][j] = lcs_1
                else:
                    dp[i][j] = lcs_2
    return dp[len_a][len_b]

print(lcs_dynamic_planning('hello world', 'hero word'))

結果如下:

heo word
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章