📜  门| GATE 2017 MOCK II |问题 7(1)

📅  最后修改于: 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")]