本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目来自牛客网的华为机试题库,本题目为中等题HJ65 查找两个字符串a,b中的最长公共子串
HJ65 查找两个字符串a,b中的最长公共子串
描述
查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。
注:子串的定义:将一个字符串删去前缀和后缀(也可以不删)形成的字符串。请和“子序列”的概念分开! 数据范围:字符串长度1≤length≤300
进阶:时间复杂度:O(n^3) ,空间复杂度:O(n)
输入描述:
输入两个字符串
输出描述:
返回重复出现的字符
示例1
输入:
abcdefghijklmnop
abcsafjklmnopqrstuvw
输出:
jklmnop
代码
while True:
try:
s1 = input()
s2 = input()
if len(s1) < len(s2):
s1,s2 = s2,s1
l1 = len(s1)
l2 = len(s2)
dp = [[0]*(l1+1) for _ in range(l2+1)]
k = m = 0
for i in range(1,l2+1):
for j in range(1,l1+1):
if s1[j-1] == s2[i-1]:
dp[i][j] = dp[i-1][j-1] + 1
if dp[i][j] > m:
m = dp[i][j]
k = i
print(s2[k-m:k])
except:
break
解析
用动态规划来解,因为如果有重复的就输出短字符串里先出现的那个。所以用s2表示较短的,作为行,最后输出的时候也是从s2输出
具体方法:
1.调整s1和s2,使得s2表示较短的字符串(方便后续操作),用m表示目前最长的相等字符串起始位置,k表示目前最长的相等字符串长度
2.生成行数为len(s1),列数为len(s2)的矩阵
3.每个位置保存到这里为止相等字符串最大长度
4.因为表示目前最长的相等字符串起始位置,k表示目前最长的相等字符串长度,所以要找到字符串是s2[k-m:k],输出即可