说明

给一个字符串str,要求用O(n)的时间复杂度求出其中最长回文子串的长度

实现步骤

基本过程

求最大回文子串的长度一般要看原串的长度是奇数还是偶数,然后分别求得,但Manacher算法的第一个神奇之处就是把两种字符串都化为长度为奇数,从而简化计算:public static char[] manacherString(String str) {

char[] charArr = str.toCharArray();

char[] res = new char[str.length() * 2 + 1];

int index = 0;

for(int i = 0;i <= res.length;i++)

res[i] = (i & 1) == 0 ? '#' : charArr[index++];

return res;

}

例如原来是aaaba,变化之后就是#a#a#a#b#a#,无论原来是奇数还是偶数,变化之后都是奇数,方便处理

概念引入

manacher算法引入三个重要概念:已知回文串的中心位置C

回文串的最右边界R

每个字符的回文半径数组pArr

C就是不断遍历的位置,只会向右不会向左。R就是最远的回文半径到了右边哪,有更大的就更新,没有就不变,所以R只会越来越向右,不会回退。pArr[]就是把每个位置的回文半径保存起来

确定回文半径

假设现在求出了pArr[0,...,i-1],现在要求i的值,分三种情况

如图,黑色部分是当前求出的最长回文直径,C是这个最长回文直径的回文中心,现在要求的是i位置的最长回文半径是多少。蓝色部分是i关于c的对称点i'的回文半径,具体值就是pArr[i'],现在的情况是蓝色的左边界超过了C的左边界,那么i的回文半径就确定是pArr[i]=R - i,为什么不可能更长,假设i的回文半径跟i'是一样的,那i的回文半径就一定能伸展到R的外面,那么这样的话黑色部分应该也会伸长,可是黑色部分只有这么长,说明R后面的字符不足以给i构成更长的回文半径

如图,蓝色部分在黑色部分里面,这是第二种情况,那就很简单了,pArr[i] = pArr[i']

最后一种情况,如图,蓝色部分正好和黑色部分的边界重合,这个时候就不能肯定R后面的字符能否是的i'的回文半径更长,需要去判断

其实还有一种情况,就是i如果在R的外面,这种情况就只能暴力去扩展,看i的最长回文半径有多长。

manacher代码public static char[] manacherString(String str) {

char[] charArr = str.toCharArray();

char[] res = new char[str.length() * 2 + 1];

int index = 0;

for(int i = 0;i < res.length;i++)

res[i] = (i & 1) == 0 ? '#' : charArr[index++];

return res;

}

public static int maxLcpsLength(String str) {

if(str == null || str.length() == 0)

return 0;

char[] charArr = manacherString(str);

int[] pArr = new int[charArr.length];//回文半径数组

int C = -1,R = -1;//回文中心和回文最右边界

int max = Integer.MIN_VALUE;

for(int i = 0;i != charArr.length;i++) {

pArr[i] = R > i ? Math.min(pArr[2 * C - i],R - i) : 1;

while(i + pArr[i] < charArr.length && i - pArr[i] > -1) {

if(charArr[i + pArr[i]] == charArr[i - pArr[i]])

pArr[i]++;

else

break;

}

if(i + pArr[i] > R) {

R = i + pArr[i];

C = i;

}

max = Math.max(max,pArr[i]);

}

return max - 1;

}

总结

看到manacher的算法流程,我想到了另一个算法——kmp,两者最初的方法时间复杂度都是O($n^2$),但是由于通过各种方法,使得有一个参照的东西能够加快进度,时间复杂度变为O(n),比方说kmp里,加速的东西就是next数组,而manacher就是回文半径数组pArr。这提供了一个很好思路,以后优化什么算法,从记录值来着手,说不定能发现一个更优秀的算法

例题

Manacher php,Manacher算法相关推荐

  1. Manacher Algorithm马拉车算法详解

    Manacher Algorithm马拉车算法详解 链接:https://www.zhihu.com/question/37289584/answer/465656849 中心扩展算法 我们先来看一个 ...

  2. manacher(马拉车)算法详解

    manacher算法,用于求字符串中最长回文串.凡是涉及暴力枚举,一般都会超时,尤其当考虑回文串时,必须前后一起判断,复杂度太高.这时,manacher算法在O(n)时间里解决问题.下面看算法. 回文 ...

  3. 回文字符串—回文子串—Manacher算法

    leetcode地址:5. 最长回文子串 解答参考:动态规划.中心扩散.Manacher 算法 问题描述: 给你一个字符串 s,找到 s 中最长的回文子串.比如给定字符串s = "babad ...

  4. 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串 (转)...

    作者:寒小阳 时间:2013年9月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/11969497. 声明:版权所有,转载请注明出处,谢谢 ...

  5. C语言noip复赛知识点,NOIP复赛知识点简述及复赛算法总结!

    全国青少年信息学奥林匹克联赛(National Olympiad in Informatics in Provinces,简称NOIP) 转眼已到了下半年,马上将迎来一场重要的比赛--NOIP. 考前 ...

  6. 动态规划问题思想及算法

    基本思想 若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解. 通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问 ...

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

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

  8. bzoj 2565: 最长双回文串 manacher算法

    2565: 最长双回文串 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem. ...

  9. 谈谈我对Manacher算法的理解

    Manacher算法其实是求字符串里面最长的回文. ①在学习该算法前,我们应该知道回文的定义:顺序读取回文和逆序读取回文得到的结果是一样的,如:abba,aba. 那么我们不难想到,在判断一个字符串s ...

最新文章

  1. 监控录像帮忙找回医院被偷的女婴
  2. core控制器属性注入的用处_了解ASP.NET Core 依赖注入,看这篇就够了
  3. 华为三层交换机路由配置案例_{华为HCNP-RS}三层交换机的配置实例
  4. 简单看java异常栈
  5. java 基本类型 引用_java中 引用类型 和 基本类型 有何区别?
  6. SSIS hang with unhandle exception
  7. 柱底反力求和lisp软件_AutoLISP 基础——认识自定义函数
  8. LINUX下载编译nasm
  9. AI人工智能服务器安装说明书,AI人工智能电脑配置及服务器双显卡的安装总结...
  10. 卡王。卡皇一个不为人知的密秘.必看(转)
  11. android—AOSP、AOKP、CM的区别
  12. 图像处理中的一阶偏导数和二阶偏导数
  13. JavaScript学习第十九天
  14. R语言文本挖掘展示:画词云图
  15. 分享湖南软大自动健康打卡思路
  16. 全民热衷“合成大西瓜”,游戏外挂上热搜,不愧是程序员!
  17. 安装windows远程桌面服务器,如何安装应用,以便在 Windows Server 远程桌面服务中使用...
  18. iOS应用架构谈 网络层设计方案
  19. Gulp.js—比Grunt更易用的前端构建工具-前端自动化
  20. laydate控件选择类型

热门文章

  1. 重磅!2021QS世界大学学科排名发布:88所中国内地高校上榜!
  2. 性能测试(一):性能测试关心的结果
  3. 编程任务编号 O: 五人列队
  4. 12306——(三)在线订票助手工具源码
  5. 点击按钮的动画,点击出现阴影,松开后逐渐扩散到整个按钮
  6. 领域驱动设计基础-《复杂软件设计之道:领域驱动设计全面解析与实战》笔记 - 1
  7. SQL Server 删除表及删除表中数据的方法
  8. 手把手教你grid布局
  9. java事务异常 try catch throw new BusinessException
  10. C++ 后缀表达式求值