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

37 阅读3分钟

字符串最短循环子串

一、问题重现

问题描述

小M在研究字符串时发现了一个有趣的现象:某些字符串是由一个较短的子串反复拼接而成的。如果能够找到这个最短的子串,便可以很好地还原字符串的结构。你的任务是给定一个字符串,判断它是否是由某个子串反复拼接而成的。如果是,输出该最短的子串;否则,输出空字符串""

例如:当输入字符串为 abababab 时,它可以由子串 ab 反复拼接而成,因此输出 ab;而如果输入 ab,则该字符串不能通过子串的重复拼接得到,因此输出空字符串。


测试样例

样例1:

输入:inp = "abcabcabcabc"
输出:'abc'

样例2:

输入:inp = "aaa"
输出:'a'

样例3:

输入:inp = "abababab"
输出:'ab'

样例4:

输入:inp = "ab"
输出:''

样例5:

输入:inp = "abcdabcdabcdabcd"
输出:'abcd'

样例6:

输入:inp = "b"
输出:''

二、解题思路

算法思路

  1. 问题理解

    • 给定一个字符串 inp,我们需要判断它是否可以由某个子串重复拼接而成。
    • 如果可以,返回最短的重复子串;否则,返回空字符串 ""
  2. 数据结构选择

    • 使用字符串切片和循环来处理字符串。
  3. 算法步骤

    • 从字符串的第一个字符开始,尝试找到一个子串,使得该子串可以重复拼接成原字符串。

    • 对于每个可能的子串长度 end,检查以下条件:

      • 子串的第一个字符与当前字符相同。
      • 原字符串的长度是子串长度的整数倍。
    • 如果满足上述条件,进一步检查该子串是否可以重复拼接成原字符串。

    • 如果找到这样的子串,返回该子串;否则,继续尝试下一个可能的子串长度。

    • 如果所有可能的子串长度都不满足条件,返回空字符串 ""

算法实现

  1. 外层循环

    • for end in range(1, len(inp) // 2 + 1):尝试所有可能的子串长度,从 1 到 len(inp) // 2
    • 这是因为如果子串长度大于 len(inp) // 2,那么它不可能重复拼接成原字符串。
  2. 条件检查

    • if inp[end] == inp[begin] and len(inp) % end == 0:检查子串的第一个字符是否与当前字符相同,并且原字符串的长度是否是子串长度的整数倍。
  3. 内层循环

    • start = [i * end for i in range(num)]:生成子串的起始位置列表。
    • for i in range(end) 和 for j in range(1, num):检查子串是否可以重复拼接成原字符串。
  4. 返回结果

    • 如果找到满足条件的子串,返回该子串;否则,返回空字符串 ""

三、代码实现

def solution(inp: str) -> str:
    # Edit your code here
    begin = 0
    for end in range(1, len(inp) // 2 + 1):
        if inp[end] == inp[begin] and len(inp) % end == 0:
            num = len(inp) // end
            start = [i * end for i in range(num)]
            flag = False
            for i in range(end):
                for j in range(1, num):
                    if inp[start[j - 1] + i] != inp[start[j] + i]:
                        flag = True
                        break
                if flag:
                    break
            if not flag:
                return inp[begin:end]
    return ""

四、算法复杂度

  1. 时间复杂度

    • 外层循环最多执行 len(inp) // 2 次。
    • 内层循环最多执行 end * num 次,其中 num = len(inp) // end
    • 因此,最坏情况下,时间复杂度为 O(n^2),其中 n 是字符串的长度。
  2. 空间复杂度: 主要的空间开销是 start 列表,其长度为 num,最多为 n // 2。因此,空间复杂度为 O(n)