赞
踩
给出两个字符串str1和str2,求他们的最长公共子串
str1[i]==str2[j]
,那么dp[i][j] = dp[i-1][j-1] + 1
,这意味着找到了长度更长的公共子串str1[i]!=str2[j]
,那么dp[i][j] = 0
maxLen
不断记录并更新最长公共子串的长度,若需要输出子串内容,还需要另外用start1
或start2
记录子串在str1、str2中的起始坐标str1[i]、str2[j]
改为对应dp[i+1]、[j+1]
(访问dp时,下标加1)def longestSubStr(str1,str2): """查找str1、str2的最长公共子串, 返回最长公共子串、该子串在str1的起始下标、在str2的起始下标 若没有公共子串,返回'', 0, 0""" len1 = len(str1) len2 = len(str2) maxLen,start1,start2 = 0,0,0#用于更新当前的最长公共子串 dp = [[0 for _ in range(len2+1)]for _ in range(len1+1)] for i in range(len1): for j in range(len2): #iadd1,jadd1=i+1,j+1 if str1[i] == str2[j]: dp[i+1][j+1] = dp[i][j]+1 ## else: ## dp[i+1][j+1] = 0 if (maxLen < dp[i+1][j+1]):#更新当前的最长公共子串 maxLen = dp[i+1][j+1] start1 = i-maxLen+1 start2 = j-maxLen+1 return str1[start1:start1+maxLen],start1,start2 ================= RESTART: C:\Users\13272\Desktop\最长公共子串LCS.py ================= >>> longestSubStr('fish','hisa') ('is', 1, 1) >>> longestSubStr('a','bcd') ('', 0, 0)
给出两个序列x,y,找出他们的最长公共子序列LCS(Longest Common Subsequence)
与最长公共子串的区别在于,子串必须是多个相连的字符,而子序列不一定
LeetCode 1143. 最长公共子序列(LongestCommonSubsequence)
给出两个序列x,y,找出他们的最长公共子序列LCS的长度
如s1=‘abcde’,s2=‘aceb’,返回3
思路:
dp[i][j]
表示子串x[0:i]
和子串y[0:j]
的最长公共子序列长度套路:两个字符串的动态规划,一般都需要二维dp数组,i、j分别与两个字符串挂钩
- 如果是“连续”的子串问题,i与以s1[i]结尾的子串挂钩
- 若果是“不连续”的子序列问题,i与s1[0…i]的子序列挂钩
dp[0]...dp[i-1]
,怎么求dp[i]
:对于字符s[i]
,可以将其拼接到其他递增序列上,求其中的最大值x[i]==y[j]
,那么dp[i][j] = dp[i-1][j-1] + 1
,这意味*找到了长度更长的公共子序列str1[i]!=str2[j]
,那么dp[i][j] = max(dp[i-1][j],dp[i][j-1])
x[0:i-1]
和y[0:j]
的LCS or 子串x[0:i]
和y[0:j-1]
的LCS,选择较大的那一个)实现:
dp[i]、[j]
改为对应x[i-1]、y[j-1]
(访问dp时,下标加1)def printLcs(flag,a,i,j): global ans if i==0 or j==0: return if flag[i][j]=='OK': printLcs(flag,a,i-1,j-1) ans.append(a[i-1]) elif flag[i][j]=='Left': printLcs(flag,a,i,j-1) else: printLcs(flag,a,i-1,j) def longSubSeq(str1,str2): len1 = len(str1) len2 = len(str2) maxLen = 0 c = [[0 for i in range(len2+1)]for i in range(len1+1)] flag = [[0 for i in range(len2+1)]for i in range(len1+1)] for i in range(len1+1): for j in range(len2+1): if i == 0 or j == 0: c[i][j] = 0 elif str1[i-1] == str2[j-1]: c[i][j] = c[i-1][j-1]+1 flag[i][j] = 'OK'# 从左上来的 maxLen = max(maxLen,c[i][j]) elif c[i][j-1] > c[i-1][j]: c[i][j] =c[i][j-1] flag[i][j] = 'Left'# 从左边来的 else: c[i][j] =c[i-1][j] flag[i][j] = 'UP'# 从上面来的 #需要获得最长公共子序列的内容时,创建全局变量ans并调用此函数 printLcs(flag,str1,len1,len2) return maxLen a='ABCBDAB' b='BDCABA' ans = [] maxLength = longSubSeq(a,b) ================= RESTART: C:\Users\13272\Desktop\最长公共序列LCS.py ================= >>> ans ['B', 'C', 'B', 'A'] >>> maxLength 4
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。