01.09. 字符串轮转
简单
提示
字符串轮转。给定两个字符串s1
和s2
,请编写代码检查s2
是否为s1
旋转而成(比如,waterbottle
是erbottlewat
旋转后的字符串)。
示例1:
输入:s1 = "waterbottle", s2 = "erbottlewat"
输出:True
示例2:
输入:s1 = "aa", s2 = "aba"
输出:False
提示:
- 字符串长度在[0, 100000]范围内。
说明:
- 你能只调用一次检查子串的方法吗?
通过次数
90.5K
提交次数
168.2K
通过率
53.8%
尝试一:s1 + s1
/**100%
思路:
1.前置判断,长度相同。
2.s2为s1的旋转,则s1 + s1包含了s1的全部旋转字符串
*/
class Solution {
public boolean isFlipedString(String s1, String s2) {
return s1.length() == s2.length() && (s1 + s1).contains(s2);
}
}
尝试二:截取拼接
提示:
如果一个字符串是另一个字符串的旋转,那么它就是在某个特定点上的旋转。例如,字符串waterbottle在3处的旋转意味着在第三个字符处切割waterbottle,并在左半部分(wat)之前放置右半部分(erbottle)。
/**14.42%
思路:
假设s2是s1的轮转字符串,那么必定从subIndex位置开始,右半部分 + 左半部分 = s1
故此遍历s2的每个字符去对比s1的第一个字符
注:可以对比出来的字符相同,只是当下这个字符相同而已,故此相同时开始用假设对比是否成立
*/
class Solution {
public boolean isFlipedString(String s1, String s2) {
//前置判断
if(s1 == null || s2 == null || s1.length() != s2.length()) return false;
if("".equals(s1) && "".equals(s2)) return true;
for(int i = 0;i < s2.length(); i++){
//遍历s2的每个字符去对比s1的第一个字符
if(s1.charAt(0) == s2.charAt(i)){
//假设成立
if(s1.equals(s2.substring(i,s2.length()) + s2.substring(0,i))){
return true;
}
}
}
return false;
}
}
尝试三:只遍历不截取
提示
想想前面的提示。再想想当你将erbottlewat与它本身连接会发生什么。你得到了erbottlewaterbottlewat。
/**23.78%
思路:
假设s2是s1的轮转字符串,那么必定从i位置开始,右半部分 + 左半部分 = s1
故此遍历s2的每个字符去对比s1的第一个字符
每次遍历到相同位置的字符串后立马开始遍历当前位置与s1[0]一直遍历为止看看是否成立
注:可以对比出来的字符相同,只是当下这个字符相同而已,故此相同时开始用假设对比是否成立
*/
class Solution {
public boolean isFlipedString(String s1, String s2) {
//前置判断
if(s1 == null || s2 == null || s1.length() != s2.length()) return false;
if("".equals(s1) && "".equals(s2)) return true;
for(int i = 0;i < s2.length(); i++){
//遍历s2的每个字符去对比s1的第一个字符
if(s1.charAt(0) == s2.charAt(i)){
//假设成立,对比检查整个字符串s2是否对应s1
boolean flag = true;
for(int j = 0;j < s1.length(); j++){
//并不是从这个位置开始旋转
if(s1.charAt(j) != s2.charAt((i + j) % s2.length())){
flag = false;
break;
}
}
if(flag) return true;
}
}
return false;
}
}