牛客网学习笔记(HJ65 查找两个字符串a,b中的最长公共子串)

204 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

题目来自牛客网的华为机试题库,本题目为中等题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],输出即可