• 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]
                    
  • 相关阅读:
    【Linux】sed笔记
    【Linux】nl笔记
    【Kubernetes】架构全图
    【Linux】tar压缩解压缩笔记
    【Docker】初识与应用场景认知
    【Ubuntu】16.04网卡信息配置
    常用枚举类
    mysql生成主键
    eclipse下mybatis-generator-config插件
    tomcat下载镜像地址
  • 原文地址:https://www.cnblogs.com/yunxintryyoubest/p/13358119.html
Copyright © 2020-2023  润新知