28.找出字符串中第一个匹配项的下标
思路
这里用kmp,复习一下;
1.把两个串拼接起来,前半部分是短串,后半部分是长串,中间加个“#”,一个循环搞定,前半部分预处理next数组,后半部分直接查表,后半部分的next相当于f了;
2.从m+2开始遍历,看能找到匹配的不,注意我的下标是从1开始,还有就是要减去前面的m+1(前半部分数组大小m以及"#'大小为1);
int nxt[20010];
class Solution {
public:
int strStr(string haystack, string needle) {
int n=haystack.size(),m=needle.size();
needle=" "+needle;
needle+="#";
needle+=haystack;
int j=0;
nxt[1]=0;
for(int i=2;i<=n+m+1;i++){
while(j>0&&needle[j+1]!=needle[i])
j=nxt[j];
if(needle[j+1]==needle[i]) j++;
nxt[i]=j;
}
int ans=-1;
for(int i=m+2;i<=n+m+1;i++){
if(nxt[i]==m){
ans=i-m+1-m-1-1;
break;
}
}
return ans;
}
};
459.重复的子字符串
思路
随想录里的思路挺妙的;
1.一个字符串如果可以由子串拼接而成,假设当前字符串由AB组成,那么BA一定也可以组成字符串;
2.这里往后面再拼一个当前字符串构成新的字符串t,判断原字符串s是否为t的子串;
3.注意t要刨头去尾,保证搜出来的是中间拼接出来的s;
int nxt[30010];
class Solution {
public:
bool repeatedSubstringPattern(string s) {
string t=s+s;
t.erase(t.begin());
t.erase(t.end()-1);
int n=t.size(),m=s.size();
s=" "+s;
s+="#";
s+=t;
int j=0;
nxt[1]=0;
for(int i=2;i<=n+m+1;i++){
while(j>0&&s[j+1]!=s[i])
j=nxt[j];
if(s[j+1]==s[i]) j++;
nxt[i]=j;
}
for(int i=m+2;i<=n+m+1;i++){
if(nxt[i]==m) return true;
}
return false;
}
};