牛客网学习笔记(动态规划-HJ65)

77 阅读2分钟

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

题目来自牛客网的华为机试题库,本题目为中等题

HJ65 查找两个字符串a,b中的最长公共子串

描述

查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。
注:子串的定义:将一个字符串删去前缀和后缀(也可以不删)形成的字符串。请和“子序列”的概念分开!
数据范围:字符串长度1≤length≤300

进阶:时间复杂度:O(n3) ,空间复杂度: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

解析

1.因为输出的是较短字符串中最先出现的子串,所以应该把较短的字符串记为s2
2.使用动态规划的方法,首先生成元素全部为0的初始化矩阵。
3.顺序更新矩阵每个位置的值,每个位置的数值表示了到这个位置为止的两个字符串相同的最大长度。如果长度超过之前的最长字串则更新输出字串的位置
4.按顺序更新到最后一行的最后一个位置,得到的k值满足就是两个字符串a,b中的最长公共子串(若有多个,输出在较短串中最先出现的那个)条件的字串最后一个字符的位置
5.输出s2[k-m:k],得到的就是满足题目条件的子串