字符串--回文串算法manachar算法
现在,我们来认识一下一个非常有意思的回文串算法manachar算法。该算法O(n)解决了如下问题: 给你一个字符串,求每一位置为中心的回文串长度。 很容易发现,最暴力的算法很容易发现是O(n2)的。 比如与到了这样一个串:aaaaaaaaaaaaaaa,每个中心都需要花费O(n)时间判断回文串长度 现在,我们就来看一看manachar算法如何解决这个问题的。 首先,由于一个串的中心可以是两个字符的间隔,所以我们需要把原串修改以下,在相邻字符中间插一个特殊字符'#',"aba"变为"#a#b#a#",这样偶数长度的回文串中心也对应一个字符了。
我们设答案数组len[],len[x]表示每个位置的回文串延伸至区间[x-len[x],x+len[x]] 我们顺序求len[],并维护一个二元组{id,mx},表示之前的右端点最右的已处理回文串的中心和半径。 我们准备求黄色部分x=16时对应len[x]值12345678901234567890123#e#c#a#b#a#c#a#b#a#c#f##e#c#a#b#a#c#a#b#a#c#f# ---------^---------S={id=12,mx=9} = [3,21]
我们发现当前位置x=16在S包含区间内,我们找到x在当前S的对应位置x'=id*2-x=8. 是不是len[x]至少为min(id+mx-x,len[x']),答案是肯定的,可以这样理解 。 由于S为回文串,可以推出如下等式 12345678901234567890123#e#c#a#b#a#c#a#b#a#c#f# ---------^--------- 又因为x'=6,len[x']=3 #e#c#a#b#a#c#a#b#a#c#f# -----^----- 想一下对应相等关系#e#c#a#b#a#c#a#b#a#c#f# -----^----- 这里相等关系已经可以由前面的信息推到,就不需要在一个一个判断了。 具体代码如下:
NOIP信息学视频地址
视频地址
链接:https://pan.baidu.com/s/1tHo1DFMaDuMZAemNH60dmw
提取码:7jgr