这是经典的找子串问题,KMP算法
class Solution {
public:
void getNext(string &str,vector<int> & next){
int j = 0;
next[0] = 0;
for(int i = 1;i< str.size();i++){
while(j > 0 && str[i] != str[j]){
j = next[j-1];
}
if(str[j] == str[i]){
j++;
}
next[i] = j;
}
}
int strStr(string haystack, string needle) {
vector<int> next(needle.size(),0);
getNext(needle,next);
int j = 0;
for(int i = 0;i< haystack.size();i++){
while(j > 0 && haystack[i] != needle[j]){
j = next[j-1];
}
if(haystack[i] == needle[j]){
j++;
}
if(j == needle.size()){
return i-needle.size()+1;
}
}
return -1;
}
};
最小重复子串如果存在的话其实就是最长前后缀子串的相对于主串的未覆盖部分
class Solution {
public:
void getNext(string & s,vector<int> & next){
int j = 0;
next[0] = 0;
for(int i = 1;i< s.size();i++){
while(j> 0 && s[i] != s[j]){
j = next[j-1];
}
if(s[i] == s[j]){
j++;
}
next[i] = j;
}
return;
}
bool repeatedSubstringPattern(string s) {
vector<int> next(s.size(),0);
getNext(s,next);
if(next[s.size()-1] == 0){
return false;
}
if(s.size() % (s.size() - next[s.size()-1]) == 0){
return true;
}
return false;
}
};
实际上这个KMP算法分为两个部分,先通过模式串来确定前缀数组,然后通过前缀数组next的记录的最大前后缀长度(如next[i] 表示[0,i]索引下的最大前后缀长度)来求解子串的位置
实在不行就背一下得了,KMP就这么个模板,都差不多