导语:距离蓝桥杯68天
问题来源Leedcode
设计思路 动态规划
寄语:
问题描述:
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
代码设计分析: 已知两段字符串 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菜鸡 一起加油!