原题链接:Leetcode 796. Rotate String
Given two strings s
and goal
, return true
if and only if s
can become goal
after some number of shifts on s
.
A shift on s consists of moving the leftmost character of s to the rightmost position.
For example, if s = “abcde
”, then it will be “bcdea
” after one shift.
Example 1:
Input: s = "abcde", goal = "cdeab"
Output: true
Example 2:
Input: s = "abcde", goal = "abced"
Output: false
Constraints:
- 1 <=
s
.length,goal
.length <= 100 s
andgoal
consist of lowercase English letters.
方法一:搜索子串
思路:
如果goal可以由s通过旋转得到,那么s一定是2倍的goal的子串
c++代码:
class Solution {
public:
bool rotateString(string s, string goal) {
return s.size() == goal.size() && (goal + goal).find(s) != string::npos;
}
};
注: npos可以表示string的结束位子,是 string::type_size
类型的,也就是find()
返回的类型。find函数在找不到指定值得情况下会返回string::npos。string::npos其实就是-1
复杂度分析:
- 时间复杂度:O(n),找子串用的KMP
- 空间复杂度:O(n),找子串用的KMP
方法二:模拟
思路:
首先还是判断连个字符串的长度;
假设 s 旋转 i 位,与 goal 中的某一位字符 goal[j] 对应。原 s 中的字符应该为 s[(i + j) mod n]。在固定 i 的情况下,遍历所有 j,若对应字符都相同,则返回 true。否则,继续遍历其他候选的 i。若所有的 i 都不能使 s 变成 goal,则返回 false。
c++代码:
class Solution {
public:
bool rotateString(string s, string goal) {
int n = s.size(), m = goal.size();
// 特判 长度是否相等
if(n != m)
return false;
// i是s的下标 j是goal的下标
for(int i = 0; i < n; i ++ ){
bool flag = true;
for(int j = 0; j < n; j ++ ){
if(s[(i + j) % n] != goal[j]){
flag = false;
break;
}
}
if(flag) return true;
}
return false;
}
};
复杂度分析:
- 时间复杂度:O(n2) 两重循环
- 空间复杂度:O(1) 没有用额外的辅助空间