📜  最长的双子序列| DP-15(1)

📅  最后修改于: 2023-12-03 14:55:23.297000             🧑  作者: Mango

最长的双子序列| DP-15

简介

本篇文章主要介绍一道经典的动态规划问题——最长的双子序列。通过此问题的解答,可以帮助读者更好地了解动态规划算法以及如何进行状态转移。

问题描述

给定两个长度相等的字符串S和T,定义S的子序列中的两个字符S[i]和S[j]是一对双子序列,当且仅当i < j 且 T 中存在字符 T[k] 满足 S[i]=S[j]=T[k]。

例如,字符串S="hello"和T="leoleh",则S中包含的所有双子序列为(h,l),(h,e),(h,o),(l,o),(l,e),(l,l),(e,o),(e,l),(o,l),(o,e)。

现在,请你编写一个程序,计算S中最长的双子序列的长度。

思路

解决本题的思路是通过动态规划,定义一个二维数组dp[i][j],其中dp[i][j]表示字符串S以第i个字符结尾,字符串T以第j个字符结尾时,S与T中的最长的双子序列长度。

对于字符串S中的第i个字符和字符串T中的第j个字符,共有以下两种情况:

  1. 若S[i]==T[j],则这两个字符可以匹配,因此最长的双子序列长度应为dp[i-1][j-1]+1。

  2. 若S[i]!=T[j],则这两个字符不能匹配,因此最长的双子序列长度应为在S的前i-1个字符和在T的前j-1个字符中S与T的最长的双子序列长度,即dp[i-1][j]或dp[i][j-1]中的较大值。

因此,转移方程可以表示为:dp[i][j] = dp[i-1][j-1]+1 (当S[i]==T[j]) 或 dp[i][j] = max(dp[i-1][j], dp[i][j-1])(当S[i]!=T[j])。

最终,所求的最长的双子序列的长度即为dp[n][n],其中n为字符串的长度。

代码实现

使用Python语言实现的代码片段如下:

def longest_common_sub_seq(S, T):
    n = len(S)
    dp = [[0] * (n + 1) for _ in range(n + 1)]
    for i in range(1, n + 1):
        for j in range(1, n + 1):
            if S[i-1] == T[j-1]:
                dp[i][j] = dp[i-1][j-1] + 1
            else:
                dp[i][j] = max(dp[i][j-1], dp[i-1][j])
    return dp[n][n]
总结

本文介绍了最长的双子序列问题的算法思路,通过动态规划的方式,实现了在时间复杂度为O(n^2)的前提下,计算两个字符串S和T之间的最长的双子序列的长度。相信读者通过学习本文,对动态规划算法和此类问题的解法有了更 深入和全面的了解,以及更多的启发和思考。