python--lintcode77.最长公共子序列

描述

给出两个字符串,找到最长公共子序列(LCS),返回LCS的长度。

 

 

 

您在真实的面试中是否遇到过这个题?  是

说明

最长公共子序列的定义:

  • 最长公共子序列问题是在一组序列(通常2个)中找到最长公共子序列(注意:不同于子串,LCS不需要是连续的子串)。该问题是典型的计算机科学问题,是文件差异比较程序的基础,在生物信息学中也有所应用。
  • https://en.wikipedia.org/wiki/Longest_common_subsequence_problem

样例

给出"ABCD" 和 "EDCA",这个LCS是 "A" (或 D或C),返回1

给出 "ABCD" 和 "EACB",这个LCS是"AC"返回 2

这一题很有意思,和公共子串我会连着讲。

思路其实也不难,设A数组长m,B数组长n,则:

dp数组为m*n,dp[i][j]代表A数组前i个数和B数组前j个数的最长子序列长度

那么我们就有了递推式:

dp[i][j]=dp[i-1][j-1]+1     if A[i]==B[j] and  i>0  and  j>0

dp[i][j]= max(   dp[i-1][j],dp[i][j-1] )    if A[i]!=B[j] and i>0 and j>0

当然需要注意的一点是,初始化第0行和第0列的时候需要把出现了相等后的所有数初始化为1,具体看代码里:

class Solution:
    """
    @param A: A string
    @param B: A string
    @return: The length of longest common subsequence of A and B
    """
    def longestCommonSubsequence(self, A, B):
        # write your code here
        m, n = len(A), len(B)
        if(m==0 or n==0): return  0
        # dp数组为m*n,dp[i][j]代表A数组前i个数和B数组前j个数的最长子序列长度
        dp=[[0 for i in range(n)] for j in range(m)]
        # 初始化第一行和第一列
        index=m+n  #记录第几个数是相等的,取m+n是为了保持比i大
        for i in range(m):
            if(A[i]==B[0] or index<=i):
                dp[i][0]=1
                index=i
        index =m+n  # 记录第几个数是相等的
        for i  in range(n):
            if(B[i]==A[0] or index<=i):
                dp[0][i]=1
                index=i
        # 开始递推
        for i in range(1,m):
            for j in range(1,n):
                if(A[i]==B[j]):
                    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-1][n-1]


s = Solution()
print(s.longestCommonSubsequence([1,2],[1,4,2,3]))

你可能感兴趣的:(python)