首页 > 编程知识 正文

Python实现最长公共子序列

时间:2023-11-21 04:57:24 阅读:294932 作者:ZLBF

本文将详细介绍如何使用Python实现最长公共子序列(Longest Common Subsequence)算法。

一、最长公共子序列简介

最长公共子序列是一种经典的动态规划问题,其目标是在两个序列中找到最长的公共子序列的长度。

公共子序列不要求子序列的元素在原序列中是连续的,只要相对顺序保持一致即可。例如,对于序列"ABCD"和"ACDF",它们的最长公共子序列是"ACD"。

二、动态规划实现

动态规划是解决最长公共子序列问题的常用方法。下面是使用动态规划算法实现最长公共子序列的Python代码:

def longest_common_subsequence(str1, str2):
    m = len(str1)
    n = len(str2)
    
    # 创建一个m行n列的二维数组,用于存储最长公共子序列的长度
    dp = [[0] * (n+1) for _ in range(m+1)]
    
    # 动态规划过程
    for i in range(1, m+1):
        for j in range(1, n+1):
            if str1[i-1] == str2[j-1]:
                dp[i][j] = dp[i-1][j-1] + 1
            else:
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])
    
    return dp[m][n]
    
str1 = "ABCD"
str2 = "ACDF"
result = longest_common_subsequence(str1, str2)
print("最长公共子序列的长度为:", result)

在上述代码中,我们使用了一个二维数组dp来记录最长公共子序列的长度。dp[i][j]表示序列str1的前i个字符和序列str2的前j个字符的最长公共子序列的长度。

在动态规划过程中,我们逐个比较str1和str2的字符,如果相等则更新dp[i][j]为dp[i-1][j-1]+1,表示当前字符在最长公共子序列中。如果不相等,则取dp[i-1][j]和dp[i][j-1]中的最大值,表示当前字符不在最长公共子序列中。

最后,返回dp[m][n]即为最长公共子序列的长度。

三、优化空间复杂度

上述代码中使用了一个二维数组dp,其空间复杂度为O(mn)。实际上,我们可以进一步优化空间复杂度为O(min(m, n)),只需使用两个一维数组来存储动态规划过程中的结果。

下面是使用优化空间复杂度的Python代码:

def longest_common_subsequence(str1, str2):
    m = len(str1)
    n = len(str2)
    
    if m < n:
        str1, str2 = str2, str1
        m, n = n, m
    
    # 创建一个长度为n+1的一维数组,用于存储最长公共子序列的长度
    dp = [0] * (n+1)
    
    # 动态规划过程
    for i in range(1, m+1):
        pre = 0
        for j in range(1, n+1):
            tmp = dp[j]
            if str1[i-1] == str2[j-1]:
                dp[j] = pre + 1
            else:
                dp[j] = max(dp[j], dp[j-1])
            pre = tmp
    
    return dp[n]
    
str1 = "ABCD"
str2 = "ACDF"
result = longest_common_subsequence(str1, str2)
print("最长公共子序列的长度为:", result)

在上述代码中,我们首先判断str1和str2的长度,保证str1的长度不小于str2的长度。

然后,我们使用一个长度为n+1的一维数组dp来存储最长公共子序列的长度。在动态规划过程中,我们只需要存储上一行的结果(pre),并通过tmp变量在更新当前行的结果时保存上一行的值。

最后,返回dp[n]即为最长公共子序列的长度。

通过以上的代码实现,我们可以方便地使用Python解决最长公共子序列问题。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。