最长的公共连续子串
原创
©著作权归作者所有:来自51CTO博客作者wx62d4c4d0ec83a的原创作品,请联系作者获取转载授权,否则将追究法律责任
一、题目描述
两个字符串(可能包含空格),找出其中最长的公共连续子串, 并输出其长度。
二、解题思路 & 代码
2.1 动态规划(二维)
创建一个二维数组 ,
其中 : 表示取到 和取到
如果 等于 ,则 等于取到 和取到 时的最大连续子串长度加 ,即 :
import sys
def maxSubStr(s1, s2):
n1 = len(s1)
n2 = len(s2)
maxLen = 0
maxEnd_1 = 0
maxEnd_2 = 0
dp = [[0] * n2 for i in range(n1)]
for i in range(n1):
for j in range(n2):
if s1[i] == s2[j]:
if (i == 0 or j == 0):
dp[i][j] = 1
else:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = 0
# 为了后续取出子串
if dp[i][j] > maxLen:
maxLen = dp[i][j]
maxEnd_1 = i # 字符串 s1 的终点位置
maxEnd_2 = j # 字符串 s2 的终点位置
return maxLen, s1[maxEnd_1 - maxLen + 1: maxEnd_1+1], s2[maxEnd_2 - maxLen + 1: maxEnd_2+1]
if __name__ == '__main__':
s1 = 's wwABC2AsssssABCA'
s2 = 'wqABC2A'
# s1 = sys.stdin.readline().strip()
# s2 = sys.stdin.readline().strip()
res = maxSubStr(s1, s2)
print(res)
输出:
(长度,从 s1 中截取的, 从 s2 中截取的)
- 时间复杂度:,M、N 分别为 两个字符串的长度
- 空间复杂度:
2.2 动态规划(
优化: 每次计算 的时候,最多只需要其左上方的
def maxSubStr_2(s1, s2):
n1 = len(s1)
n2 = len(s2)
row = 0 # 斜线开始位置的行
col = n2 - 1 # 斜线开始位置的列
maxLen = 0 # 最大长度
end = 0 # 子串的结尾位置索引
while row < n1:
i = row
j = col
curLen = 0
while i < n1 and j < n2: # 从 (i, j) 开始向右下方遍历
if s1[i] != s2[j]:
curLen = 0
else:
curLen += 1
if curLen > maxLen: # 记录最大值,以及结束字符的位置索引
end = i
maxLen = curLen
i += 1
j += 1
if col > 0: # 斜线开始位置的列先向左移动
col -= 1
else: # 列移动到最左之后,行向下移动
row += 1
return maxLen, s1[end - maxLen + 1: end + 1]
if __name__ == '__main__':
s1 = 's wwABsedC2AsssssABCA'
s2 = 'wqABesdC2A'
# s2 = 'dddd'
res2 = maxSubStr_2(s1, s2)
print("res2:", res2)
输出:
- 时间复杂度:,M、N 分别为 两个字符串的长度
- 空间复杂度:
参考:
- 动态规划-----最长公共连续子串