mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2024-09-02 14:20:01 +00:00
85 lines
2.9 KiB
Markdown
85 lines
2.9 KiB
Markdown
# [459. Repeated Substring Pattern](https://leetcode.com/problems/repeated-substring-pattern/description/)
|
||
# 思路
|
||
判断一个字符串是否由某个子字符串重复若干次构成。
|
||
注意substr的用法:
|
||
substr(pos, len): 从位置pos开始,跨越len个字符(或直到字符串的结尾,以先到者为准)对象的部分
|
||
## 思路一、直接判断
|
||
子字符串的长度从1开始递增直到找到满足题意则返回true,找不到就返回false。
|
||
时间复杂度O(n^2), 空间复杂度O(1)
|
||
## 思路二、循环移位
|
||
类似思路一,只是判断是否满足题意时用了比较trick的方法,时间亲测稍快于思路一,但是牺牲了空间。
|
||
若当前子串长度为i,则若满足题意,则将s循环移位i位后的字符串应该与s相等。
|
||
时间复杂度O(n^2), 空间复杂度O(n)
|
||
## 思路三、next数组
|
||
求s的next数组(从0开始的版本),记next数组的最后一个元素为p,若p > 0 并且 size % (size - p) == 0,返回True.
|
||
时间复杂度O(n),空间复杂度O(n)
|
||
|
||
|
||
# C++
|
||
## 思路一
|
||
```C++
|
||
class Solution {
|
||
private:
|
||
// bool isOK(string s, const int &sub_len){
|
||
// for(int i = 0; i < sub_len; i++){
|
||
// for(int j = 1; j < s.size() / sub_len; j++)
|
||
// if(s[j * sub_len + i] != s[(j-1) * sub_len + i]) return false;
|
||
// }
|
||
// return true;
|
||
// }
|
||
bool isOK(string s, const int &sub_len){ // 这种写法比上面的更简洁貌似也更快
|
||
for(int i = 1; i < s.size() / sub_len; i++)
|
||
if(s.substr(i * sub_len, sub_len) != s.substr(0, sub_len)) return false;
|
||
return true;
|
||
}
|
||
public:
|
||
bool repeatedSubstringPattern(string s) {
|
||
for(int i = 1; i <= s.size() / 2; i++){
|
||
if(s.size() % i != 0) continue;
|
||
if(isOK(s, i)) return true;
|
||
}
|
||
return false;
|
||
}
|
||
};
|
||
```
|
||
## 思路二
|
||
```
|
||
class Solution {
|
||
private:
|
||
string leftShift(string &str, int l){
|
||
string ret = str.substr(l); // substr(pos, len): 从位置pos开始,跨越len个字符(或直到字符串的结尾,以先到者为准)对象的部分
|
||
ret += str.substr(0, l);
|
||
return ret;
|
||
}
|
||
public:
|
||
bool repeatedSubstringPattern(string str) {
|
||
string nextStr = str;
|
||
int len = str.length();
|
||
if(len < 1) return false;
|
||
for(int i = 1; i <= len / 2; i++){
|
||
if(len % i == 0){
|
||
nextStr = leftShift(str, i);
|
||
if(nextStr == str) return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
};
|
||
```
|
||
## 思路三
|
||
```
|
||
class Solution {
|
||
public:
|
||
bool repeatedSubstringPattern(string str) {
|
||
int i = 1, j = 0, n = str.size();
|
||
vector<int> next(n+1,0);
|
||
while( i < str.size() ){
|
||
if( str[i] == str[j] ) next[++i]=++j;
|
||
else if( j == 0 ) i++;
|
||
else j = next[j];
|
||
}
|
||
return next[n]&&next[n]%(n-next[n])==0;
|
||
}
|
||
};
|
||
```
|