Leedcode最长公共子序列 Python每日一练

导语:距离蓝桥杯68天 

 问题来源Leedcode 

设计思路 动态规划

 寄语:Leedcode最长公共子序列 Python每日一练_第1张图片

问题描述:Leedcode最长公共子序列 Python每日一练_第2张图片

class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        text1,text2=' '+text1,' '+text2
        n,m=len(text1),len(text2)
        dp=[[0]*n for i in range(0,m)]#n为列,m为行
        for j in range(1,m):#遍历行
            for k in range(1,n):#每一行中 遍历列
                if text1[k]==text2[j]:
                    dp[j][k]=dp[j-1][k-1]+1
                else:
                    dp[j][k]=max(dp[j-1][k],dp[j][k-1])
        ans=0
        for _ in dp:
            ans=max(ans,max(_))
        return ans

 Leedcode最长公共子序列 Python每日一练_第3张图片

代码设计分析: 已知两段字符串 A,B

为方便描述,我们初始化:在A,B最前面加上一个空格,代表‘空’元素

dp[i][j]代表A中第i个元素结尾的子串与B中以第j个元素结尾的子串的最长公共序列

如果A中第i个元素与B中以第j个元素相同 那么显而易见 dp[i][j]=dp[i-1][j-1]+1

否则 dp[i][j]=max(dp[i-1][j],dp[i][j-1])

着重解释dp[i][j]=max(dp[i-1][j],dp[i][j-1]):

很多人包括我自己一开始也想不明白这个下标的问题?仔细一想 还是有道理在里面的

首先:题目要求 A和B的最长公共子序列 先考虑这样一个问题:

如果A和B的长度越长,那么出现公共子序列的长度是不是越大?(是的,因为元素多了,重复的可能性就增大了)

因此我们每次考虑A子串与B子串的最长公共子序列,都要尽可能使得两者长度尽可能长!才能使得最终A和B的公共子序列最长(贪心)

所以当A子串与B子串的末尾元素不同时,我们要求A子串与B子串的最长公共子序列,最贪心的做法就是取dp[i-1][j]和dp[i][j-1]中较大的那个 ,比如dp[i-1][j],就是求A子串前i-1个元素与B子串前j个元素的最大子序列长度(已经不可能有比这个更大了的了因为已经达到最长了),dp[i][j-1]同理。

 新年快乐 我是小郑 一个正在准备蓝桥杯的Py菜鸡 一起加油!

 

你可能感兴趣的:(Python,笔记,蓝桥杯,python,蓝桥杯,贪心算法,leetcode)