【字符串】萌萌哒的manacher算法

来源:互联网 发布:c语言做窗口按钮 编辑:程序博客网 时间:2024/05/16 17:45

是时候刷一阵博客了(博客以前居然叫部落格... >.<)
manacher算法是一个可以O(n)的时间计算一个字符串的回文子串的算法(搞法)。参考了网上的很多资料,终于以量取胜把脑洞补上了。
基本的资料请拨打baidu.com脑补,这里主要解释一下思路:
首先假设你已经求得了rad[1 .. k]的回文半径,其中有一个点i比较特殊,把它的回文半径接上后它就鹤立鸡群了,即装备了自己的回文半径后攻击范围最远的那个位置i。
对于一个未知的位置,比如k之后的一个角落j, 如果它的位置落在这个前文中i的延伸范围(攻击范围...)中,那么它就萌萌哒的发现(自己早上进了个球...)它的回文匹配工作可以利用前人的结果,所以它就洗个澡,开瓶酒,叫个外卖,算一下
min(rad[i - j + i], i + rad[i] - j)
然后就把自己登录到rad里面回头把工作推给j+1了。
这个时候j+1不服气啊,它说你啥都没干怎么就把工作都给我了?
于是j振振有词的解释道:(no zuo no die)由于我被i的回文半径所覆盖,而i的回文存在对称性,所以我有一个镜像(就是i - j + i,也就是 2 * i - j的来历,话说加法比乘法快谁跟我说的...)已经在前文中进行了匹配工作,但是i的回文范围是有限的,所以i的回文不一定完全把那个镜像的回文半径完全覆盖,未覆盖的部分不能保证镜像可以继续拓展它的回文范围,所以这里可以跳过的工作需要取它们的最小值,即min(rad[i - j + i], i + rad[i] - j),j+1你了懂不?
j+1不禁暗暗艾特了一下李福菊,但是它脑子一转,不对啊,虽然未覆盖的部分不能保证j的镜像可以继续拓展它的回文范围,但是反过来说j的回文半径说不定可以继续拓展啊(因为i的回文半径后的部分是未知的),想到这里,j+1一狠心就向主线程抛出了一个异常,于是j顺利地被Rollback了(主线程:怪我咯)。
于是字符们继续进行着自己兢兢业业的工作,虽然j走了,但是它的思想永垂不朽,大家使用这种减少重复匹配的方法先进行延伸,在尝试在i的覆盖范围外继续拓展,字符串的最长回文子串就可以顺利求出了。
不过大家还记得j临走前说过的最后一句话么 ——“我今天没有吃药,感觉自己萌萌哒!”
为了纪念j的工作成果,代码什么的以后在补了...

0 0