77. 最长公共子序列

77. 最长公共子序列

中文English

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

样例

样例 1:
	输入:  "ABCD" and "EDCA"
	输出:  1
	
	解释:
	LCS 是 'A' 或  'D' 或 'C'


样例 2:
	输入: "ABCD" and "EACB"
	输出:  2
	
	解释: 
	LCS 是 "AC"

说明

最长公共子序列的定义:

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

第一个版本:同向型双指针

存在弊端,它前面匹配成功,则直接会跳到后面去匹配,按照A的字符串顺序在B字符串进行匹配

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):
        #检测边界
        if not A or not B:
            return 0

        #初始条件
        l = len(A)
        d = [1] * len(A)

        max_num = 0
        #计算顺序
        for i in range(l):
            j = B.find(A[i])   
            #边界情况
            if j != -1:
                max_num = max(self.getCommonSubsequence(A[i:],B[j:],i,j),max_num)

        return max_num

    
    def getCommonSubsequence(self,A,B,i,j):
        #传入切割后的A和B进来
        p = 0
        j = 0 
        for i in range(len(A)):
            if A[i] in B[j:]:
                p += 1
                j += B[j:].find(A[i])
        return p

注:lintcode不通过,方法不可行

第二个版本:动态规划(匹配型动态规划)

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
        #动态规划,匹配型
        
        #初始化
        len1, len2 = len(A), len(B)
        #存在null的情况
        dp = [[0 for _ in range(len2 + 1)] for _ in range(len1 + 1)]
        
        #计算顺序
        for i in range(1,len1 + 1):
            for j in range(1, len2 + 1):
                #如果两者不相等,只需要判断最大即可
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
                #如果该A和B的字符相等,则是上一个字符加1,dp[i][j]表示的是在A的前i个字符串中,匹配j的最长个数
                if (A[i - 1] == B[j -1]):
                    #毫无疑问,这里+1肯定是最大的,会一直更新,直到最后
                    dp[i][j] = dp[i - 1][j - 1] + 1 
                
        return dp[len1][len2]
                

 

posted @ 2020-07-21 23:28  风不再来  阅读(192)  评论(0编辑  收藏  举报