题解 | #公共子串计算#

公共子串计算

https://www.nowcoder.com/practice/98dc82c094e043ccb7e0570e5342dd1b

两种方法选其一,暴力法可以倒序遍历,找到公共子串即可break减少循环次数,动态规划注意第一个值相等时的处理

# fun是暴力法,fun_dp是动态规划,选其一都行
def fun():
    s1, s2 = input(), input()
    max_com_sub_s = ""
    s1, s2 = (s1, s2) if len(s1) < len(s2) else (s2, s1)  # s1是短的
    for i in range(len(s1)):  # 遍历短的
        for j in range(len(s1), i, -1):  # 从末尾开始遍历,有子串时即可退出
            if s1[i:j] in s2 and len(s1[i:j]) > len(max_com_sub_s):  # 找到子串并且长度更大
                max_com_sub_s = s1[i:j]  # 替换最大子串
                break
    print(len(max_com_sub_s))


def fun_dp():
    s1, s2 = input(), input()
    s1, s2 = (s1, s2) if len(s1) < len(s2) else (s2, s1)  # s1是短的
    dp = [[0 for _ in s2] for _ in s1]  # s1的i位和s2的j位时的最大公共子串长度
    max_len, max_com_sub_s = 0, ""
    for i in range(0, len(s1)):  # 遍历s1的每个位置
        for j in range(0, len(s2)):  # 遍历s2的每个位置
            if s1[i] == s2[j]:  # 当前位置相等时,
                if i == 0 or j == 0:  # 如果是开头,那自然是1
                    dp[i][j] = 1
                else:  # 动态转移方程为s1 s2上一位的dp值+1
                    dp[i][j] = dp[i - 1][j - 1] + 1
                if dp[i][j] > max_len:  # 更新最大值,因为最大值不是dp[-1][-1]
                    max_len = dp[i][j]
                    max_com_sub_s = s2[j - max_len + 1 : j + 1]
    print(len(max_com_sub_s))


fun()

全部评论

相关推荐

11-30 11:07
河南大学 Java
宇宙厂 测开 n*15
丘丘给个offer:有后选后
点赞 评论 收藏
分享
10-24 13:36
门头沟学院 Java
Zzzzoooo:更新:今天下午有hr联系我去不去客户端,拒了
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务