题解 | 查找两个字符串a,b中的最长公共子串
def find_longest_common_substring(a, b):
# 获取字符串长度
m, n = len(a), len(b)
# 初始化 DP 数组
dp = [[0] * (n + 1) for _ in range(m + 1)]
# 记录最长子串的长度和结束位置
max_length = 0
end_pos = 0 # 在字符串 a 中的结束位置
# 填充 DP 数组
for i in range(1, m + 1):
for j in range(1, n + 1):
if a[i - 1] == b[j - 1]: # 如果字符相同
dp[i][j] = dp[i - 1][j - 1] + 1
# 更新最大长度和结束位置
if dp[i][j] > max_length:
max_length = dp[i][j]
end_pos = i
else:
dp[i][j] = 0 # 不相同则置为 0
# 提取最长公共子串
longest_common_substring = a[end_pos - max_length:end_pos]
return longest_common_substring
# 示例
a = input()
b = input()
if len(a) > len(b):
a, b = b, a
result = find_longest_common_substring(a, b)
print(result)
思路:
动态规划可以高效解决最长公共子串问题。
- 创建一个二维数组
dp,其中dp[i][j]表示字符串a的前i个字符和字符串b的前j个字符中,以a[i-1]和b[j-1]结尾的最长公共子串的长度。 - 如果
a[i-1] == b[j-1],则dp[i][j] = dp[i-1][j-1] + 1; - 如果
a[i-1] != b[j-1],则dp[i][j] = 0; - 在遍历过程中,记录最长长度及其结束位置,然后根据结束位置提取最长公共子串。
例如a字串:babcde,b字串:abcda,结果如下
b字串 | 0 | a | b | c | d | a | |
a字串 | |||||||
0 | 0 | 0 | 0 | 0 | 0 | 0 | |
b | 0 | 0 | 1 | 0 | 0 | 0 | |
a | 0 | 1 | 0 | 0 | 0 | 0 | |
b | 0 | 0 | 2 | 0 | 0 | 0 | |
c | 0 | 0 | 0 | 3 | 0 | 0 | |
d | 0 | 0 | 0 | 0 | 4 | 0 | |
e | 0 | 0 | 0 | 0 | 0 | 0 |

查看21道真题和解析