Manacher时间复杂度证明

如果想了解更多内容,欢迎关注我的微信公众号:信息学竞赛从入门到巅峰。

 

今天,我们来证明一下Manacher的时间复杂度。

先贴上Manacher算法的模板: 

s[0] = '$'; s[++m] = '#';
for (b = 1; ss[b] != '\0'; ++b) {
    s[++m] = ss[b];
    s[++m] = '#';
}
s[++m] = '?';
for (int i = 1; i < m; ++i) {
    if (maxid > i) p[i] = min(maxid-i, p[2*id-i]);
    else p[i] = 1;
    while (s[i-p[i]] == s[i+p[i]]) p[i]++;
    if (i + p[i] > maxid) {
        maxid = i + p[i];
        id = i;
    }
}

我们考虑产生复杂度的地方,分别是最外层对整个字符串的遍历和每次对回文串扩展的while。

显然,最外层的for循环是O(N)的,那么我们只需要证明while的总循环次数也是O(N)级别的即可。

很容易发现,每次进入while,回文串的最大覆盖范围都会加1.(为什么呢?)

1、如果以i位置的为回文中心的回文串的基础长度没有超出当前回文串的最大覆盖范围,那么显然不会进入while中(由于对称性,该回文串的长度已经最大了)。

2、如果以i位置的为回文中心的回文串的基础长度超出了当前回文串的最大覆盖范围,那么显然每进入一次while,回文串的最大覆盖范围都会加1.

那么,当最大覆盖范围包含了整个字符串之后,while循环就不会在进入了。所以while循环的总次数为O(N)。

综上所述,Manacher算法的时间复杂度为O(N)。

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值