class Solution {
public int strStr(String haystack, String needle) {
if(needle.length()==0){
return 0;
}
int[] next=new int[needle.length()];
Next(needle,next);
int j=-1;
for(int i=0;i<haystack.length();++i){
while(j!=-1&&haystack.charAt(i)!=needle.charAt(j+1)){
j=next[j];
}
if(haystack.charAt(i)==needle.charAt(j+1)){
++j;
}
if(j==needle.length()-1){
return i-j;
}
}
return -1;
}
void Next(String needle,int[] next){
int j=-1;
next[0]=-1;
for(int i=1;i<needle.length();++i){
while(j!=-1&&needle.charAt(i)!=needle.charAt(j+1)){
j=next[j];
}
if(needle.charAt(i)==needle.charAt(j+1)){
++j;
}
next[i]=j;
}
}
}
这个KMP时间复杂度怎么这么高,介于这个算法我老忘。我就简单抄一遍《算法笔记》上的介绍。。。
next[i]就是子串s[0…i]的最长相等前后缀的前缀最后一位的下标。
暴力求解next可行,但要用“递推”的方法来高效求解next数组。
(1)初始化next数组,令j=next[0]-1。
(2)让i在1~len-1范围遍历,对每个i,执行(3)(4),以求解next[i]
(3)不断令j=next[j],直到j回退到-1,或是s[i]==s[j+1]成立
(4)如果s[i]==s[j+1],则next[i]=j+1;否则next[i]=j。
KMP算法和求解next数组的代码十分相似,求解next数组的过程其实就是模式串进行自我匹配的过程。