码迷,mamicode.com
首页 > 编程语言 > 详细

37:密码截取(回文串manacher算法)

时间:2016-08-28 17:58:48      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

题目描述:Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?

输入描述:输入一个字符串

输出描述:返回有效密码串的最大长度

输入例子:

ABBA

输出例子:

4

思路:最长回文串的长度

Manacher算法O(n)

因为对于偶回文,是需要从虚轴扩充,ab,ba,所以如下:

先把原字符串处理,都加上一个标记符,比如#(特殊字符任何都可以,对于计算结果不会有影响)

1221-->#1#2#2#1#

121-->#1#2#1#

按照处理后的字符串求它的最长回文串长度m,所以原始字符串最长子回文串的长度是m/2

 

变量:

1:PArra[] 存放回文半径:某个位置能扩充的回文半径的长度,例如 #1#2#2#1#,2位置PArra[3] = 4

2:int PR 能够扫到的最右的回文的位置   #1#2#1# 在位置3   PR = 6

3:int  index   当 PR更新的时候,index也要更新,指向当前最中心的位置   2中index=3

过程:

当要求位置i的时候的回文半径   分析如下:

1:第一种情况可以直接确定i的回文半径,PR不变,因为没有扩

技术分享  

 

 

2:第二种情况,i‘的左边在index左边的左边,PR不用变化,(没有扩)也可以直接确定i位置的回文半径

技术分享

3:第三种情况,i‘的左边喝index的左边重复,需要从  “右大位置开始继续扩”

如何算复杂度:

如果扩成功了,说明,超过了目前的右大更新PR

技术分享

4:第四种情况必须暴力扩

 技术分享

 

每一次检查的时候,要么失败,要么成功扩,只要成功扩了,PR必须更新,而且最长扩也就2n,所以“扩”的动作和PR高度相关;

通过变量优化这个算法的时候,一般这个复杂度和这个变量的增量有关。

 

 

37:密码截取(回文串manacher算法)

标签:

原文地址:http://www.cnblogs.com/newcoder/p/5815389.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!