旋转串指的是通过将一个字符串的开头字符依次移到结尾形成的新字符串。例如,字符串 "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 - 1(n是列表长度)。 - 内层循环控制第二个字符串的索引
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)。由于这个操作是在双重循环内部调用的,所以整体算法的时间复杂度主要由双重循环决定,仍然是 。