马拉车,O(n)求回文串

对整个马拉车算法步骤做个总结:

  • 第一步:将每个原字母用两个特殊字符包围如:
aaa --> #a#a#a#
abab -->#a#b#a#b
同时可以由这个翻倍的字符串得到一个性质:
如果在此串中,以特殊字符,如'#'为回文中心,那么在原串中回文长度就是偶数,如果是以正常字符为回文中心,那么在原串中的回文长度就是奇数

这样可以使得所有的奇数长度的回文串变成偶数长度

  • 第二步:设置P数组P[N*3];代表S[i]的回文半径(包括自身),并设置id为迄今为止回文半径最大的字符位置,max为id+P[id],该回文串的右边界位置

  • 第三步:求p数组,这里存在一个结论:

    如果mx > i,那么P[i] >= min(P[2 * id - i], mx - i)。

    2id-i,将其转化到x坐标上看,正好是i关于id的对称点,可以这么理解:由于mx>i,可知i-->mx是在已知范围以内的,因为以i为回文中心的回文串是与以其关于对称点j=2id-i存在长度至少为mx-i相同回文半径的。

    如图:(x和y至少是同样长的,因为以j为中心的是回文串,同id同i,根据回文串性质可得)

  • 第四步:对于p数组的认识,p数组是在原字符串翻倍后的基础上进行运算的,很显然,若p[i]=6,那么原串的回文长度(不是回文半径)是5 :设原半径为ans,回文长度为len,那么len=ans2-1;而此时半径为x=ans2,转化可得len=x-1;

这里贴上两份模板

模板1:

void init()
{
len1=strlen(s);
str[0]='(';
str[1]='#';
for(int i=0;i<len1;i++)
{
str[i*2+2]=s[i];
str[i*2+3]='#';
}
len2=len1*2+2;
str[len2]=')';
}
void Manacher()
{
memset(p,0,sizeof(p));
int id=0,mx=0;
for(int i=1;i<len2;i++)
{
if(mx>i) p[i]=min(mx-i,p[2*id-i]);
else p[i]=1;
for(;str[i+p[i]]==str[i-p[i]];p[i]++);
if(p[i]+i>mx)
{
mx=p[i]+i;
id=i;
}
}
}

模板2:

int Init(int n)
{
cpy[0]='(';cpy[1]='#';
for(int i=0,j=2;i<n;j+=2,i++)
{
cpy[j]=a[i];
cpy[j+1]='#';
}
n=n*2+3;
cpy[n-1]=')';
return n;
}
void Manacher(char *s,int n,int *p)
{
for(int i=1,j=0,k;i<n;i+=k)
{
while(s[i-j-1]==s[i+j+1]) j++;
p[i]=j;
for(k=1;k<=p[i]&&p[i-k]!=p[i]-k;k++)
{
p[i+k]=min(p[i-k],p[i]-k);
}
j=max(j-k,0);
}
}

最新文章

  1. Java获取某年第一天和最后一天
  2. php配置rewrite模块
  3. Linux_rsylogd日志
  4. VS2010设置C++包含目录和库目录
  5. JAVA中集合输出的四种方式
  6. ocp 1Z0-047 61-130题解析
  7. HTML5学习(九)----应用程序缓存
  8. Android开发心得(转)
  9. C#读取json数据介绍
  10. Junit4拓展工具JCategory与Testng的Group功能比较
  11. __file__ __name__ __doc__ argv详解
  12. FTS下载地址
  13. Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析
  14. AutoFac学习摘要
  15. bzoj5102: [POI2018]Prawnicy
  16. vc++读取文件属性的详细信息描述 通过读取QQ的注册表和EXE路径两种方式
  17. Nginx配置跨域请求“Access-Control-Allow-Origin”
  18. java基础-day20
  19. 全网最详细的Oracle10g/11g的官方下载地址集合【可直接迅雷下载安装】(图文详解)
  20. [Spring Boot] @Component, @AutoWired and @Primary

热门文章

  1. 19_传智播客iOS视频教程_类和对象
  2. Maximum Gap 典型线性排序
  3. bzoj 1044: [HAOI2008]木棍分割【二分+dp】
  4. 清北考前刷题day4早安
  5. [Swift通天遁地]一、超级工具-(8)地图视图MKMapView的常用代理方法
  6. 论文翻译-SELF TRAINING AUTONOMOUS DRIVING AGENT
  7. Window对象与DOM
  8. 用Movie显示gif(2)GifView
  9. Spring Cloud学习(一)
  10. 使用_CRTDBG_LEAK_CHECK_DF检查VC程序的内存泄漏(转)