📅  最后修改于: 2023-12-03 15:42:10.295000             🧑  作者: Mango
本题目是GATE 2017 MOCK II中的第7道习题,它主要是考察了字符串的相关操作和算法。
本题的输入是一个长度为n的字符串,以及非负整数m。要求编写一个算法,找出该字符串中所有长度为m的子串,同时输出这些子串在原字符串中的起始位置。
我们可以用两种方法解决这个问题。
第一种方法是从左到右遍历字符串,每读到一个m长度的子串就记录下其起始位置、结束位置以及子串的内容。依次类推直至遍历完整个字符串。时间复杂度是O(nm)。
def find_all_substrings(str, m):
n = len(str)
result = []
for i in range(n-m+1):
result.append((i, i+m-1, str[i:i+m]))
return result
第二种方法是使用滑动窗口,我们首先记录下第1~m个字符的下标范围,并计算其哈希值。然后我们移动窗口,将子串最左边的字符从哈希值中减去,将新字符加入哈希值中,可以实现在O(1)时间内更新哈希值。我们逐个比较哈希值,如果相同则说明找到一个目标子串。时间复杂度是O(n)。
def find_all_substrings(str, m):
n = len(str)
result = []
if n < m:
return result
# Compute the hash of the first window.
target_hash = hash(str[:m])
window = str[:m]
for i in range(1, n-m+1):
if hash(window) == target_hash:
result.append((i-1,i+m-2,window))
window = window[1:] + str[i+m-1]
if hash(window) == target_hash:
result.append((n-m,n-1,window))
return result
以下是一些测试样例:
assert find_all_substrings("ababa", 3) == [(0,2,"aba"), (2,4,"aba")]
assert find_all_substrings("aaabbb", 2) == [(0,1,"aa"), (1,2,"aa"), (2,3,"bb"), (3,4,"bb")]
assert find_all_substrings("abcde", 5) == [(0,4,"abcde")]