KMP模板推导

两串匹配问题

假设我们有两个长度分别为 n,m 的串 s,t。我们现在要找出 ts 中所有出现位置的左端点下标。

枚举左端点暴力匹配的复杂度最坏是 O(nm),用单一字母可以构造出数据。

但是我们发现,对于前面的匹配区间,后面的匹配区间和它可能有两种关系:

  1. 无交
    两者求解独立,同时不影响复杂度。
  2. 有交
    相交部分对于前面的区间是个后缀,对于后面的区间是个前缀。
    但是这前、后两个区间都是能和 t 串匹配的。
    所以相交部分就是 t 的一个 border

所以我们现在就要知道一些 border 的性质,来方便维护这个东西。

关于 border 的性质以及具体匹配方法

关于 border 有个显然的性质

对于一个串,它 borderborder 也是它的 border

假设我们在 s[l,r] 的位置和 t 产生了一次成功的匹配。

由于后面的匹配区间和 s[l,r] 的交必定是 s[l,r] 的一个 border
但是这个 border 不一定是最大的那个。
为了方便处理,我们考虑先将当前变成最大的那个 border,然后逐渐变小来判断合法性。

现在问题是怎么维护。考虑维护一个最大 j,使得 s[rj+1,r]=t[1,j]。每次将 r 这个右端点往右移动,
相对应的为了满足条件,我们会尝试不断地让 t[1,j] 变成其最大 border,使得其下一个字符能匹配上,

t 整个串再一次都匹配上时,就重复这个过程。

现在问题就只在于,怎么对每个 t 的前缀,预处理出其最长 border

t 每个前缀的最长 border

我们记要求解的东西——所有 t[1,i] 的最长 border 长度为 nxti

一个对 nxt 数组的理解:nxti 表示的不只是 t[1,i] 的最长 border,也是在当前无法匹配第 i+1 个位置时的失配指针。

我们考虑增量法求解。每次利用前面的信息处理 nxti+1
具体的,在尾部加入一个字符后,可能会有一些原本是 border 的对应串现在仍是 t[1,j] 往后加一个字符后的 border,也有一些不再是当前位置往后的 border

故而我们利用已有的所有 nxt 信息,从大到小访问所有 border,并且找到最大的合法 border 并记录。

复杂度

空间复杂度 O(n+m)

时间复杂度,考虑每次右端点往右移动 1,维护的 j 最多加 1
而每次跳 border 的时候 j 至少减 1
故而均摊时间复杂度为 O(n+m)

posted @   徐子洋  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示