判断两个字符串是否互为旋转词
旋转词
【题目】
如果一个字符串str,把字符串str前面任意的部分挪到后面形成的字符串叫作str的旋转词。
比如str=“12345”,str的旋转词 有"12345"、“23451”、“34512”、“45123"和"51234”。
给定两个字符串a和b,请判断a和b是否互为旋转词。
若a和b长度不相等,则a和b必然不互为旋转词,直接返回False
【举例】
a=“cdab”,b=“abcd”,返回True。
a=“1ab2”,b=“ab12”,返回False。
a=“2ab1”,b=“ab12”,返回True。
算法思路
b+b组合的字符串,包含b所有的旋转词,+表示字符串拼接操作
其中任意长度为n的子串都是b的旋转词,n为字符串b的长度
假设字符串b的字符表示形式为
b
=
b
0
b
1
.
.
.
b
i
.
.
.
b
n
−
1
b=b_0b_1...b_i...b_{n-1}
b=b0b1...bi...bn−1
b
[
0
:
n
]
+
b
[
0
:
0
]
=
b
0
b
1
.
.
.
b
i
.
.
.
b
n
−
1
b[0:n]+b[0:0]=b_0b_1...b_i...b_{n-1}
b[0:n]+b[0:0]=b0b1...bi...bn−1
b
[
1
:
n
]
+
b
[
0
:
1
]
=
b
1
b
2
.
.
.
b
i
.
.
.
b
n
−
1
b
0
b[1:n]+b[0:1]=b_1b_2...b_i...b_{n-1}b_0
b[1:n]+b[0:1]=b1b2...bi...bn−1b0
…
b
[
i
:
n
]
+
b
[
0
:
i
]
=
b
i
b
i
+
1
.
.
.
b
n
−
1
b
0
b
1
.
.
.
b
i
−
1
b[i:n]+b[0:i]=b_ib_{i+1}...b_{n-1}b_0b_1...b_{i-1}
b[i:n]+b[0:i]=bibi+1...bn−1b0b1...bi−1
…
b
[
n
:
n
]
+
b
[
0
:
n
]
=
b
0
b
1
.
.
.
b
i
.
.
.
b
n
−
1
b[n:n]+b[0:n]=b_0b_1...b_i...b_{n-1}
b[n:n]+b[0:n]=b0b1...bi...bn−1
第i个长度为n的字符串为前i个字符移至后面的旋转词
因此b+b包含b所有的旋转词,其中任意长度为n的子串都是b的旋转词
判断a与b是否互为旋转词,只需判断a是否包含在组合字符串b+b中,在则互为旋转词,不在则不互为旋转词
字符串匹配使用KMP算法,时间复杂度为
O
(
N
)
O(N)
O(N)
注意:
KMP算法可本地自行实现,详见字符串匹配;
也可使用字符串库函数
str1.find(str2)
,若包含,返回第一次出现的位置,否则返回-1;
str1.index(str2)
,若包含,返回第一次出现的位置,否则抛出异常ValueError: substring not found
。
为简单起见,才用字符串库函数find()
完成本题。
相应代码
# 判断两个字符串是否互为旋转词
def rotate_word(a, b):
if a is None or b is None or len(a) == 0 and len(b) == 0 or len(a) != len(b):
return False
rotate_str = b + b
if rotate_str.find(a) != -1: # KMP算法,采用字符串库函数find()
return True
else:
return False
# 简单测试
if __name__ == '__main__':
a = "cdab"
b = "abcd"
print(rotate_word(a, b)) # True
a = "1ab2"
b = "ab12"
print(rotate_word(a, b)) # False
a = "2ab1"
b = "ab12"
print(rotate_word(a, b)) # True
有任何疑问和建议,欢迎在评论区留言和指正!
感谢您所花费的时间与精力!