题目描述
链接:https://www.nowcoder.com/questionTerminal/02e7cc263f8a49e8b1e1dc9c116f7602
时间限制:3秒;空间限制:32768K
对于两个字符串,请设计一个时间复杂度为O(m*n)的算法(这里的m和n为两串的长度),求出两串的最长公共子串的长度。这里的最长公共子串的定义为两个序列U1,U2,..Un和V1,V2,...Vn,其中Ui + 1 == Ui+1,Vi + 1 == Vi+1,同时Ui == Vi。
给定两个字符串A和B,同时给定两串的长度n和m。
测试样例:
"1AB2345CD",9,"12345EF",7 返回:4
解题思路
本题求的时最长公共子串,和求最长公共子序列的区别在于子串必须连续。可以构建大小为n*m的矩阵z,矩阵上对应位置z[i][j]代表A[i]与B[j]是否相同,只有在一条连续斜线上的数均相同,代表该位置为AB两串的公共字串。于是,对于z[i][j],若A[i]与B[j]不相等则赋值为0;若相等则取z[i-1][j-1]的值加1,用以代表当前公共字串长度。最终输出整个矩阵z的最大值,即为最长公共子串长度。
测试样例对应的矩阵z为:
[[1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 2, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 3, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 4, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]]
示例程序:
# -*- coding:utf-8 -*-
class LongestSubstring:
def findLongest(self, A, n, B, m):
# write code here
z = [[0 for i in range(m)] for j in range(n)]
max_val = 0 #记录最大值
for i in range(n):
for j in range(m):
if A[i]==B[j]:
if i==0 or j==0:
z[i][j] = 1
else:
z[i][j] = z[i-1][j-1]+1
if z[i][j]>max_val:
max_val = z[i][j]
return max_val