题目链接:28. 实现 strStr()
本题是KMP 经典题目。
KMP的经典思想就是:当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。
KMP主要应用在字符串匹配上。
KMP的主要思想是当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。
所以如何记录已经匹配的文本内容,是KMP的重点,也是next数组肩负的重任。
代码如下:
int strStr(char * haystack, char * needle){
int n=strlen(haystack),m=strlen(needle);
if(m==0)
return 0;
int next[m];
next[0]=0;
for(int i=1,j=0;i<m;i++)
{
while(j>0&&needle[i]!=needle[j])
j=next[j-1];
if(needle[i]==needle[j])
j++;
next[i]=j;
}
for(int i=0,j=0;i<n;i++)
{
while(j>0&&haystack[i]!=needle[j])
j=next[j-1];
if(haystack[i]==needle[j])
j++;
if(j==m)
return i-m+1;
}
return -1;
}
题目链接:459.重复的子字符串
这道题可以通过kmp算法来解答,next 数组记录的就是最长相同前后缀,这里next[0]初始值设置为0,如果 next[len - 1] != 0,则说明字符串有最长相同的前后缀(就是字符串里的前缀子串和后缀子串相同的最长长度)。最长相等前后缀的长度为:next[len - 1]
数组长度为:len。
如果len % (len - next[len - 1] ) == 0 ,则说明数组的长度正好可以被 (数组长度-最长相等前后缀的长度) 整除 ,说明该字符串有重复的子字符串。
代码如下:
bool repeatedSubstringPattern(char * s){
int j=0;
int len=strlen(s);
if(len==0)
return false;
int next[len];
next[0]=j;
for(int i=1;i<len;i++)
{
while(j>0&&s[i]!=s[j])
j=next[j-1];
if(s[i]==s[j])
j++;
next[i]=j;
}
if(next[len-1]!=0&&(len%(len-next[len-1])==0))
return true;
else
return false;
}