今天是开始记录LeetCode刷题的第一天,先来一个简单题练练手。
今日目标是:旋转字符串。
说明如下:
说一下自己的思路,一般在见到两个字符比较的时候,我首先想到的就是双指针,因为这基本不需要额外的空间,且时间复杂度大概率为O(N),所以我们开始构建脑图。
首先,排除两个字符串不相等的情况
int len1 = s.length();
int len2 = goal.length();
if (len1 != len2) {
return false;
}
然后建立指针,i指向s,j指向goal。
这道题的难点在于如何使用一个变量记录字符的旋转,那么我们想一下,他是按顺序的旋转的,所以我们可以将s的每次旋转都想想成将当前的首位字符复制到最后面,但是我们需要限制字符串的长度,即限制字符串的起点和终点。
所以,s每次旋转,我们都让i+1,直到找到与goal首位匹配的字符的下标。
此时,匹配剩余的字符,会遇到两种情况,
- 当遇到i溢出时(因为我们不是真的给s扩容了,只是在理论上给其扩容),我们需要考虑如何获取正确的s的下一个下标。
举个例子比较好明白点,假设字符串为“abc”
因为旋转是顺序旋转的,第一次旋转时,在理论中字符串变成“abca”,此时我们需要获取的是第二个‘a’,那他的下标其实就是i % len(s)。
- 当j移动到字符goal末尾,那么说明,匹配成功了。
所以完整代码如下
public boolean rotateString(String s, String goal) {
int len1 = s.length();
int len2 = goal.length();
if (len1 != len2) {
return false;
}
// 双指针
int i = 0, j = 0;
// i 最多移动2 * len - 1 步,在移动就回到了最开始的位置
while (i < 2 * len1 - 1) {
// 旋转,找到与goal 的第一个字符匹配的字符
while (i < len1 && goal.charAt(j) != s.charAt(i)) {
i++;
}
int temp = i;
// 找到之后
do {
temp++;
j++;
} while (j < len1 && s.charAt(temp % len1) == goal.charAt(j));
// 跳出情况有两种情况 1、j 2、不等
if(j == len1){
return true;
}
j = 0;
i++;
}
return false;
}
附leetcod图: