KMP:在一个字符串中找一个子串
28. 实现 strStr()
前缀表统一-1
class Solution {
public:
int strStr(string haystack, string needle) {
int n=needle.length();
int m=haystack.length();
if(n==0) return 0;
int next[n];
getNext(next,needle);
int i=0,j=-1;
for(int i=0;i<haystack.length();i++)
{
while(j>=0&&haystack[i]!=needle[j+1])
{
j=next[j];
}
if(haystack[i]==needle[j+1])
{
j++;
}
if(j==n-1)
{
return i-needle.size()+1;
}
}
return -1;
}
void getNext(int* next,string s)
{
int i=0,j=-1;
next[0]=-1;
int n=s.length();
for(int i=1;i<n;i++)
{
while(j>=0&&s[i]!=s[j+1])
{
j=next[j];
}
if(s[i]==s[j+1])
{
j++;
}
next[i]=j;
}
}
};
前缀表不减一 (个人认为更好理解)
class Solution {
public:
int strStr(string haystack, string needle) {
int n=needle.length();
int m=haystack.length();
if(n==0) return 0;
int next[n];
getNext(next,needle);
int i=0,j=0;
for(int i=0;i<m;i++)
{
while(j>0&&haystack[i]!=needle[j])
{
j=next[j-1];
}
if(haystack[i]==needle[j])
{
j++;
}
if(j==n)
{
return i-n+1;
}
}
return -1;
}
void getNext(int* next,string s)
{
int i=0,j=0;
next[0]=0;
for(int i=1;i<s.length();i++)
{
while(j>0&&s[i]!=s[j])
{
j=next[j-1];
}
if(s[i]==s[j])
{
j++;
}
next[i]=j;
}
}
};
459.重复的子字符串
这题虽然标的是easy,但是很难啊 qaq 利用KMP的next的数组,非常巧妙。
KMP的next数组的含义是前后缀的最大长度t,t!=0且s.length()%(s.length()-t)==0,说明由重复字符串构成!!
class Solution {
public:
bool repeatedSubstringPattern(string s) {
int n=s.length();
if(n==0) return false;
int next[n];
getNext(next,s);
if(next[n-1]!=0&&n%(n-next[n-1])==0) return true;
else return false;
}
void getNext(int* next,string s)
{
int i=0,j=0;
next[j]=0;
for(int i=1;i<s.length();i++)
{
while(j>0&&s[i]!=s[j])
{
j=next[j-1];
}
if(s[i]==s[j])
{
j++;
}
next[i]=j;
}
}
};