旋转串匹配 | 豆包MarsCode AI刷题

45 阅读3分钟

旋转串指的是通过将一个字符串的开头字符依次移到结尾形成的新字符串。例如,字符串 "abc" 可以通过旋转变成 "bca" 和 "cab",他们之间互为旋转串。你的任务是判断在给定的字符串集合中,是否存在两个字符串互为旋转串。


测试样例

样例1:

输入:n = 3, s = ["abb", "abc", "bab"]
输出:True

样例2:

输入:n = 3, s = ["aba", "abc", "abb"]
输出:False

样例3:

输入:n = 4, s = ["abc", "bca", "cab", "bac"]
输出:True

def solution(n: int, s: list) -> bool:
    for i in range(n):
        for j in range(i + 1, n):
            if is_rotation(s[i], s[j]):
                return True
    return False


def is_rotation(s1: str, s2: str):
    if len(s1)!= len(s2):
        return False

    return s2 in s1 + s1

if __name__ == '__main__':
    print(solution(3, ["abb", "abc", "bab"]) == True)
    print(solution(3, ["aba", "abc", "abb"]) == False)
    print(solution(4, ["abc", "bca", "cab", "bac"]) == True)

1. 整体算法思路

这段代码实现的算法主要用于在给定的字符串列表中,查找是否存在两个字符串满足其中一个是另一个的循环旋转形式。其核心思路是通过双重循环遍历列表中的每一对字符串,然后针对每一对字符串使用特定的判断方法来确定是否为循环旋转关系。

2. 具体算法步骤

2.1 遍历字符串对

在 solution 函数中:

收起

python

复制

def solution(n: int, s: list) -> bool:
    for i in range(n):
        for j in range(i + 1, n):
            if is_rotation(s[i], s[j]):
                return True
    return False
  • 首先使用两层嵌套的 for 循环来遍历输入的字符串列表 s。外层循环控制第一个字符串的索引 i,从 0 遍历到 n - 1n 是列表长度)。
  • 内层循环控制第二个字符串的索引 j,从 i + 1 开始遍历到 n - 1。这样的设置确保了每一对字符串只会被比较一次(避免了重复比较同一个字符串对自身以及重复比较已经比较过的字符串对)。

2.2 判断循环旋转关系

对于每一对字符串 s[i] 和 s[j],通过调用 is_rotation 函数来判断它们是否存在循环旋转关系:

收起

python

复制

def is_rotation(s1: str, s2: str):
    if len(s1)!= len(s2):
        return False

    return s2 in s1 + s1
  • 第一步,先进行长度判断。如果两个字符串 s1 和 s2 的长度不相等,那么它们肯定不可能是循环旋转关系,所以直接返回 False。这是基于循环旋转的性质,循环旋转后的字符串长度是不变的。
  • 第二步,若长度相等,就通过将 s1 与其自身拼接(s1 + s1)形成一个新的字符串。然后检查 s2 是否在这个拼接后的字符串中。如果 s2 在 s1 + s1 中,就意味着 s2 可以通过对 s1 进行循环旋转得到,此时返回 True;反之,如果 s2 不在 s1 + s1 中,就返回 False

3. 算法时间复杂度分析

  • 对于 solution 函数中的双重循环部分,外层循环执行 n 次(n 为字符串列表的长度),内层循环对于外层循环的每一次迭代,平均执行大约 n / 2 次(因为内层循环从 i + 1 开始)。所以双重循环的时间复杂度大致为 ,这里的 n 是输入字符串列表的长度。
  • 对于 is_rotation 函数,判断字符串长度是否相等的操作时间复杂度为 (因为只是简单的比较操作)。而检查 s2 是否在 s1 + s1 中的操作,在最坏情况下,时间复杂度为 ,其中 m 是字符串的长度(假设 s1 和 s2 长度相等且为 m)。由于这个操作是在双重循环内部调用的,所以整体算法的时间复杂度主要由双重循环决定,仍然是 。