扩展 (KMP) 可以 (O(n)) 得出一个字符串的 (z) 函数,(z(i)) 为以 (i) 开头的后缀和整个串的 (lcp)。
维护一个 (r) 最大的和前缀匹配的子串 ([l,r]),当前的 (z) 函数可以从之前得到的结果继承过来,剩下的部分暴力匹配,因为每个位置最多被暴力匹配一次,所以复杂度为 (O(n))。
z[1]=n;
for(int i=2;i<=n;++i)
{
if(i<=r) z[i]=min(z[i-l+1],r-i+1);
while(i+z[i]<=n&&s[i+z[i]]==s[z[i]+1]) z[i]++;
if(i+z[i]-1>r) l=i,r=i+z[i]-1;
}