LeetCode/solutions/459. Repeated Substring Pattern.md
2019-09-13 23:08:41 +08:00

85 lines
2.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# [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;
}
};
```