题目459.重复的子字符串
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
示例 1:
输入: “abab”
输出: True
解释: 可由子字符串 “ab” 重复两次构成。
示例 2:
输入: “aba”
输出: False
示例 3:
输入: “abcabcabcabc”
输出: True
解释: 可由子字符串 “abc” 重复四次构成。(或者子字符串 “abcabc” 重复两次构成。)
class Solution {
public:
//KMP法
//得到next数组,存放的是对应字符最大相等前后缀大小
void getNext (int* next, const string& s){
next[0] = -1;//初始化
int j = -1; //代表最长前后缀大小
//遍历,要从下标1开始,下标为0的已经在上面初始化了
for(int i = 1;i < s.size(); i++){
//比较
//当不匹配时,回溯
while(j >= 0 && s[i] != s[j+1]) {
//回溯到前一位字符对应的前后缀大小
j = next[j];
}
//当匹配上时,前后缀大小加1
if(s[i] == s[j+1]) {
j++;
}
next[i] = j;
}
}
bool repeatedSubstringPattern (string s) {
//首先判断是否为空字符串,若是直接返回false
if (s.size() == 0) {
return false;
}
int next[s.size()];
getNext(next, s);
int len = s.size();
//对于这个判断条件,其实动手写个例子就能看懂了
if (next[len - 1] != -1 && len % (len - (next[len - 1] + 1)) == 0) {
return true;
}
return false;
}
};
next[len - 1] != -1
如果是重复子字符串,那么最后一位字符所对应的最大前后缀肯定不是-1
len - (next[len - 1] + 1)
得到的是剩余子字符串,如果len%l(en - (next[len - 1] + 1))==0,也就是刚好整除,那么肯定由重复字符串构成。动手画一下就非常清楚了。