版权声明:欢迎转载,请注明作者和出处 https://blog.csdn.net/baichoufei90/article/details/83281078
算法学习-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