回文字符串 Manacher
阅读原文时间:2023年07月08日阅读:1

忘光了,忘光了。

首先将字符串所有字符之间(包括头尾)插入相同分隔符,再在最前方插入另一个分隔符防止越界。

设以 \(s_i\) 为对称中心的回文串中,最长的回文半径为 \(p_i\)。记录在所有遍历过的位置中(\(1\sim i-1\)),以任意一个点为对称中心的回文串的右端点最大值 \(r\),即 \(r=\max_{j=1}^{i-1}s_j+p_j-1\),记 \(d\) 即为取到这个最大值的对称中心。注意 \(r\) 和 \(d\) 是实时更新的

对于当前位置 \(i\):

  • 若 \(i>r\),则暴力求 \(p_i\),此时每次扩展都会将 \(r\) 向右移动 \(1\)

  • 若 \(i\leq r\),则先将 \(p_i\) 赋值为 \(\min(r-i+1,p_{2d-i})\),再逐位扩展。

    说明:因为位置 \(2d-i\) 与 \(i\) 是对称的(在 \(d\) 的最长回文半径范围内),所以在 \([d-p_d+1,d+p_d-1\ (r)]\) 范围内,\(2d-i\) 的回文串也是 \(i\) 的回文串。若 \(p_{2d-i}<r-i+1\),那么根据对称性,\(p_i\) 的最终值就等于 \(p_{2d-i}\)。否则 \(p_i=r-i+1\),每次扩展都会将 \(r\) 向右移动 \(1\)

综上,总时间复杂度为 \(\mathcal{O}(n)\)。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章