屌毛算法导致我直接罢工两天没心情做题。
KMP就是用来解决匹配问题,比如字符串中找重复子串。
核心就是一个next数组
含义:next[i]即 以i为结尾的非前缀字串 和 前缀 能够匹配的最大长度。没有的话可以为0
abaabaaaa
next[5]就是因为aba和 aba 相匹配,为3
如果直接枚举next数组的话,显然不如直接暴力枚举字符串,因此就有了优化
引理:如果j为next[i]的一个候选项,则小于j的最大的next[i]的候选项是next[j]
即next[i]候选项是 j next[j] next[next[j]] …的非0元素
证明:若存在next[j]<h<j,h为next[i]的候选项,原本next[j]就会被更大的取代。不满足每个next最大的性质
优化:
如果j是next[i]的候选项,那么j-1也是next[I-1]的候选项(长度为j的字符串相等那么 长度为j-1的必然也相等)
因此,计算next[i]只需要计算next[i-1]+1 next[next[I-1]]+1…
核心代码:
next[1]=0;
for(int i=2,j=0;i<=n;i++){
while(j>0&&a[i]!=a[j+1])
j=next[j];
if(a[i]==a[j+1]) j++;
next[i]=j;
}