已知两个字符串X和Y,其中X包含m个字符,Y包含n个字符,找出两者之间的 最长公共子序列,即在X和Y中从左到右都出现的连续的最长字符串序列。例如, X=“ABCBDAB”,Y=“BCBDDAB”,则X和Y的最长公共子序列即为{“CBD”,“DBA”}, 由该例可知,最长公共子序列可能不唯一。
时间: 2023-11-27 09:05:25 浏览: 31
这是一个经典的问题,可以使用动态规划算法来解决。我们可以用一个二维数组dp[m+1][n+1]来表示X和Y的最长公共子序列的长度。其中dp[i][j]表示X的前i个字符和Y的前j个字符的最长公共子序列的长度。那么状态转移方程为:
如果X[i-1] == Y[j-1],则dp[i][j] = dp[i-1][j-1] + 1;
如果X[i-1] != Y[j-1],则dp[i][j] = max(dp[i-1][j], dp[i][j-1])。
最终的结果即为dp[m][n],这个值表示X和Y的最长公共子序列的长度。如果要求出具体的子序列,可以倒推回去,从dp[m][n]开始,根据状态转移方程依次向左上方或左方或上方进行查找,直到回到dp[0][0]为止。
代码实现如下:
```python
def longest_common_subsequence(X, Y):
m, n = len(X), len(Y)
dp = [[0] * (n+1) for _ in range(m+1)]
for i in range(1, m+1):
for j in range(1, n+1):
if X[i-1] == Y[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
else:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
# 回溯找出具体的子序列
i, j = m, n
res = []
while i > 0 and j > 0:
if X[i-1] == Y[j-1]:
res.append(X[i-1])
i -= 1
j -= 1
elif dp[i-1][j] >= dp[i][j-1]:
i -= 1
else:
j -= 1
return ''.join(res[::-1])
```
例如,对于X=“ABCBDAB”,Y=“BCBDDAB”,可以调用longest_common_subsequence(X, Y)函数来得到它们的最长公共子序列“CBDAB”。