字符串最短循环子串 | 豆包MarsCode AI刷题

77 阅读2分钟

解题思路:

要找到一个字符串的最短循环子串,我们需要理解如果存在这样的子串,它一定满足以下条件:整个字符串是由这个子串重复若干次构成的。这意味着原字符串长度必须是该子串长度的整数倍。我们的目标是最小化这个子串的长度。

寻找最短循环子串的方法

  1. 初始化:获取输入字符串 inp 的长度 n
  2. 遍历可能的子串长度:从长度 1 开始尝试,直到 n // 2(包括),因为如果子串长度超过一半,即使重复两次也不能覆盖整个字符串。
  3. 检查是否为整数倍:对于每一个可能的子串长度 l,我们检查 n % l == 0,即检查 n 是否能被 l 整除。只有当 n 是 l 的整数倍时,才有可能形成循环子串。
  4. 生成候选子串并验证:取字符串 inp 的前 l 个字符作为候选子串 candidate。然后我们将此候选子串重复 n // l 次,并与原始字符串 inp 进行比较。如果两者相等,则找到了最短循环子串。
  5. 返回结果:一旦找到符合条件的最短循环子串,立即返回。如果没有找到任何循环子串,则返回空字符串 "" 表示不存在这样的子串。

Python 实现代码

def find_shortest_repeating_substring(s):
    length = len(s)
    
    # Iterate over all possible substring lengths up to half the length of the string
    for i in range(1, length // 2 + 1):
        if length % i == 0:
            # Generate a candidate substring and check if it can form the original string when repeated
            candidate = s[:i]
            if candidate * (length // i) == s:
                return candidate
    
    # If no repeating substring is found, return an empty string
    return ""

复杂度分析

  • 时间复杂度:O(n),其中 n 是字符串的长度。这是因为我们在最坏的情况下需要遍历至多一半的字符串长度,并且每次迭代都涉及一次字符串比较。
  • 空间复杂度:O(1),除了用于存储临时变量和候选子串外,算法不需要额外的空间。然而,生成重复字符串的操作在Python中会创建新的字符串对象,这实际上增加了空间使用,但在理论上讨论时我们通常忽略这一点。

总结

这种方法提供了一种简单而有效的方式来查找最短循环子串。通过逐步增加子串长度并验证其能否构造出原始字符串,我们可以确保找到最小的重复单位。这种技术不仅适用于这个问题,也可以应用于其他需要检测周期性模式的问题。