面试题 01.09. 字符串轮转
题目描述
字符串轮转。给定两个字符串s1
和s2
,请编写代码检查s2
是否为s1
旋转而成(比如,waterbottle
是erbottlewat
旋转后的字符串)。
示例1:
输入:s1 = "waterbottle", s2 = "erbottlewat" 输出:True
示例2:
输入:s1 = "aa", "aba" 输出:False
提示:
- 字符串长度在[0, 100000]范围内。
说明:
- 你能只调用一次检查子串的方法吗?
解法
方法一:字符串匹配
首先,如果字符串 $s1$ 和 $s2$ 长度不相等,那么肯定不是旋转字符串。
其次,如果字符串 $s1$ 和 $s2$ 长度相等,那么将两个 $s1$ 连接,得到的 $s1 + s1$ 这个字符串一定包含了 $s1$ 旋转的所有情况,这时候我们只要判断 $s2$ 是否是 $s1 + s1$ 的子串即可。
# 成立
s1 = "aba"
s2 = "baa"
s1 + s1 = "abaaba"
^^^
# 不成立
s1 = "aba"
s2 = "bab"
s1 + s1 = "abaaba"
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $s1$ 的长度。
Python3
class Solution:
def isFlipedString(self, s1: str, s2: str) -> bool:
return len(s1) == len(s2) and s2 in s1 * 2
Java
class Solution {
public boolean isFlipedString(String s1, String s2) {
return s1.length() == s2.length() && (s1 + s1).contains(s2);
}
}
C++
class Solution {
public:
bool isFlipedString(string s1, string s2) {
return s1.size() == s2.size() && (s1 + s1).find(s2) != string::npos;
}
};
Go
func isFlipedString(s1 string, s2 string) bool {
return len(s1) == len(s2) && strings.Contains(s1+s1, s2)
}
TypeScript
function isFlipedString(s1: string, s2: string): boolean {
return s1.length === s2.length && (s2 + s2).indexOf(s1) !== -1;
}
Rust
impl Solution {
pub fn is_fliped_string(s1: String, s2: String) -> bool {
s1.len() == s2.len() && (s2.clone() + &s2).contains(&s1)
}
}
Swift
class Solution {
func isFlippedString(_ s1: String, _ s2: String) -> Bool {
return (s1.isEmpty && s2.isEmpty) || (s1.count == s2.count && (s1 + s1).contains(s2))
}
}