51 Nod http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1089

Manacher 算法

定义数组 p[i]表示以i为中心的(包含i个这个字符)回文串半径长.

将字符串s从前扫到后,来计算p[i] , 则最大的p[i]就是最长回文串长度 ,

由于s是从前扫描到最后的,所以需要计算p[i]时一定计算好了 p[1]~~p[i-1]

假设现在扫描到了i+k这个位置,现在需要计算p[i+k]

定义maxlen是位置i+k位置前所有回文串中能延伸到的最有右端的位置 ,即maxlen=p[i]+i; // p[i]表示半径长 , i 表示目前最长的位置 , //这有两种情况 .

1 : i+k 这个位置不在前面的任何回文串中 , 即 i+k>maxlen , 则促使换p[i+k]=1 ; //  意思就是本身就是一个回文串 , 此时的长度的为 1 --> p[i+k]=1 ; 然后p[i+k]左右延伸,即while(s[i+k+p[i+k]]==s[i+k]-p[i+k])   ++p[i+k];  // 这样计算出来 p[i+k]的长度 .

2 : i+k 这个位置被前面以位置i为中心的回文串包含,即maxlen>i+k;这样的话p[i+k]就不是从1开始的 .

由于回文串的性质 , 可知i+k这个位置与关于 i 的i-k对称,所以p[i+k]分为一下三种情况得出 ,

// 黑色的是i的回文串范围,蓝色的是i-k的回文串范围.

然后就是三种情况了

第一种情况  :  i-k 回文串有一部分在 i 的回文串之外 , 如上图蓝色左端在黑色右端之外 , 这种情况p[i+k]=p[i]-k;  // 这时候就有人会有疑惑了 , p[i-k]那里的长度比你上面上的p[i]-k要长呀 ? 很正确虽然p[i-k]的长度长但是 p[i]的延伸最终在那里终止了 就说明 i+p[i]和i-p[i]是不相同的两个符号 , 所以p[i+k]的长度最多只是 , p[i]-k;

第二种情况  :  i-k的回文串全部在p[i]之内 , 所以p[i+k]=p[i-k]那么这是的p[i+k]会不会更长呢 , 不可能 原因的话自己想想 .

第三种情况  :  i-k的右端和i的右端重合 , 这时候 p[i+k]最小是p[i]-k ; 并且可能继续增加 .

//  NYOJ 的答案

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<string>
#include<sstream>
#include<map>
#include<cctype>
#include<limits.h>
using namespace std;
char s[220000];         // s  是      模式串
int p[220000];                   //             表示  以 i 为中心 情况下 最长的   长度
int main()
{while(scanf("%s",s)!=EOF){memset(p,0,sizeof(p));int len=strlen(s),id=0,maxlen=0;                        //  字符串长度   ,for(int i=len;i>=0;--i)                        // 插入 # 解决 , 长度为奇偶的问题 .{                             //插入'#'s[i+i+2]=s[i];s[i+i+1]='#';}                                       //插入了len+1个'#',最终的s长度是1~len+len+1即2*len+1,首尾s[0]和s[2*len+2]要插入不同的字符s[0]='*';                                       //s[0]='*',s[len+len+2]='\0',防止在while时p[i]越界for(int i=2;i<2*len+1;++i)   // 完善好字符串之后 ,
        {if(p[id]+id>i)p[i]=min(p[2*id-i],p[id]+id-i);  //   如果超过的话 , 右边(p[id]+id-i)的大 如果不超过的话 左边(p[2*id-i])的 大elsep[i]=1;while(s[i-p[i]] == s[i+p[i]])    // 第 26 -- 29 , 32 33  都是为了 减小时间复杂度 来设置的 .p[i]++;if(id+p[id]<i+p[i])    // 这个 id+p[id] 是模式串中已经解决的 最右端 问题 .id=i;if(maxlen<p[i])maxlen=p[i];}cout<<maxlen-1<<endl;}return 0;
}

转载于:https://www.cnblogs.com/A-FM/p/5517958.html

Manacher算法 , 实例 详解 . NYOJ 最长回文相关推荐

  1. manacher算法----O(n)最长回文串

    manacher算法----O(n)最长回文串 分类:字符串 (126)  (0)  举报  收藏 manacher的时间复杂度为O(n),后缀数组好像可以处理O(nlogn),但是有些变态题目可能卡 ...

  2. html5走格子游戏,JS/HTML5游戏常用算法之碰撞检测 地图格子算法实例详解

    JS/HTML5游戏常用算法之碰撞检测 地图格子算法实例详解 发布时间:2020-09-26 20:42:24 来源:脚本之家 阅读:112 作者:krapnik 本文实例讲述了JS/HTML5游戏常 ...

  3. 冒泡排序算法实例详解

    冒泡排序算法实例详解 1.复杂度与稳定性 算法时间复杂度 最坏情况:O(n^2) 最好情况:O(n) 平均情况:O(n^2) 空间复杂度:S(n)=O(1) 稳定性:稳定排序 2.过程介绍(以顺序为例 ...

  4. Manachar算法(马拉车算法):快速求取最长回文子串

    当我们求取最长回文子串时,常见的方法就是中心扩散法,即从字符中心出发,向两边对比,检查是否相等,若等于,则继续检查,并使当前字符中心对应的最长回文子串长度加一,否则,结束该字符中心的回文检查,比较与当 ...

  5. 最长回文子串动态规划_九章算法 | 微软面试题:最长回文子串

    给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串. 在线评测地址:LintCode 领扣 样例 1: 输入:"abcdzdcab&quo ...

  6. LHL算法入门经典 例题3-3最长回文子串

    ##3-3[字符串]最长回文子串 题目描述 输入一个字符串,求出其中最长的回文子串.子串的含义是:在原串中连续出现的字符串片段.回文的含义是:正着看和倒着看相同.如abba和yyxyy.在判断回文时, ...

  7. python如何调用文件进行换位加密_python 换位密码算法的实例详解

    python 换位密码算法的实例详解 一前言: 换位密码基本原理:先把明文按照固定长度进行分组,然后对每一组的字符进行换位操作,从而实现加密.例如,字符串"Error should neve ...

  8. C++longest palindromic subsequence最长回文子序列算法实现(附完整源码)

    C++longest palindromic subsequence最长回文子序列算法 C++longest palindromic subsequence最长回文子序列算法实现完整源码(定义,实现, ...

  9. 【最长回文子串】Manacher算法详解

    写在前面 manacher算法解决最长回文子串以及变形问题的时间复杂度为O(n). 如果你想囫囵吞枣,只需要使用到该算法,你可以直接把代码拿走:但如果你想深入了解这个算法的工作原理和关键部分解读,还是 ...

最新文章

  1. 初识Linux C线程
  2. 你想要的自动驾驶汽车,为何迟迟不能出现?
  3. 英国前首相:为什么欧洲没有诞生互联网巨头?
  4. Java多线程引发的性能问题,怎么解决?
  5. [转载]C++ 面试
  6. k8s服务器修改ip,[转载][K8S] Kubernetes 集群变更IP地址
  7. 解决canvas画图模糊的问题
  8. Android之开源框架NineOldAndroids动画库
  9. CF741C Arpa’s overnight party and Mehrdad’s si
  10. php 计算前几天,php计算几分钟前、几小时前、几天前的几个函数、类分享
  11. vue 利用hash值实现刷新无跳转页面
  12. Linux防火墙-netfilter filter表案列与nat表应用
  13. 对于DOM的attribute和property的一些思考
  14. porphet论文_Facebook 时间序列预测算法 Prophet 的研究
  15. 【Hoxton.SR1版本】Spring Cloud Bus消息总线
  16. 西南科技大学OJ题 最简单的C程序0612
  17. BZOJ1299 巧克力棒
  18. w7网络计算机共享,网络共享设置 win7局域网共享设置最简单教程
  19. 云服务器下行_阿里云ECS服务器下行带宽和上行带宽详解及选择
  20. java设置字体大小_java中控制字体大小的设置

热门文章

  1. 初学者应该了解的编程陷阱:javascript篇
  2. Windows日志及其保护
  3. Windows 2008 R2 SP1部署Lync2010标准版(1)
  4. 使用openpyxl去操作Excel表格
  5. 撩课-Java每天5道面试题第11天
  6. 在chrome Sources 页 显示 Console(drawer) 页
  7. Java基础系列--Executor框架(一)
  8. 算法笔记-图--bfs
  9. 【笔记】js Function类型 内部方法callee
  10. grunt合并压缩js、css文件