KMP算法
用于在字符串A中寻找是否出现过字符串B
第一步:求最长公共前后缀长度,构建Prefix Table
public static void getPrefixTable(char[] pattern,int[] prefix){
int n = pattern.length;
assert n>0;
// 每次填充一个prefix的值
prefix[0]=0;
for(int i=1,len=0;i<n;i++){
while(len>0 && pattern[len]!=pattern[i]){
len = prefix[len-1];
}
if(pattern[len]==pattern[i]){
len++;
prefix[i]=len;
}
prefix[i]=len;
}
}
第二步:利用Prefix Table完成KMP算法
- 如果Text[i]!=pattern[0] (j==0)
- i++;
- 否则,
- 先利用Prefix Table完成跳跃
- 然后判断(因为有可能跳到最后j=0,依旧有可能Text[i]!=pattern[j]),如果Text[i]==pattern[j]
- j++
- 如果j==m
- return true;
- 先利用Prefix Table完成跳跃
28. 实现 strStr() [KMP算法🌟]
class Solution {
public int strStr(String haystack, String needle) {
int n = haystack.length(), m = needle.length();
if(m==0) return 0;
// 构建Prefix Table,注意要从第2个元素开始
int[] prefix = new int[m];
for(int i=1,len=0;i<m;i++){
while (len>0 && needle.charAt(i)!=needle.charAt(len)){
len = prefix[len-1];
}
if(needle.charAt(i)==needle.charAt(len)){
len++;
}
prefix[i]=len;
}
// KMP
for(int i=0,j=0;i<n;i++){
while(j>0 && haystack.charAt(i)!=needle.charAt(j)){
j = prefix[j-1];
}
if(haystack.charAt(i)==needle.charAt(j)){
j++; //因为i自动++
}
if(j==m)
return i-m+1; //计算到开头的位置,此时i在最后一个字符的位置。
}
return -1;
}
}