Manacher php,Manacher算法
说明
给一个字符串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算法相关推荐
- Manacher Algorithm马拉车算法详解
Manacher Algorithm马拉车算法详解 链接:https://www.zhihu.com/question/37289584/answer/465656849 中心扩展算法 我们先来看一个 ...
- manacher(马拉车)算法详解
manacher算法,用于求字符串中最长回文串.凡是涉及暴力枚举,一般都会超时,尤其当考虑回文串时,必须前后一起判断,复杂度太高.这时,manacher算法在O(n)时间里解决问题.下面看算法. 回文 ...
- 回文字符串—回文子串—Manacher算法
leetcode地址:5. 最长回文子串 解答参考:动态规划.中心扩散.Manacher 算法 问题描述: 给你一个字符串 s,找到 s 中最长的回文子串.比如给定字符串s = "babad ...
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串 (转)...
作者:寒小阳 时间:2013年9月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/11969497. 声明:版权所有,转载请注明出处,谢谢 ...
- C语言noip复赛知识点,NOIP复赛知识点简述及复赛算法总结!
全国青少年信息学奥林匹克联赛(National Olympiad in Informatics in Provinces,简称NOIP) 转眼已到了下半年,马上将迎来一场重要的比赛--NOIP. 考前 ...
- 动态规划问题思想及算法
基本思想 若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解. 通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问 ...
- manacher算法----O(n)最长回文串
manacher算法----O(n)最长回文串 分类:字符串 (126) (0) 举报 收藏 manacher的时间复杂度为O(n),后缀数组好像可以处理O(nlogn),但是有些变态题目可能卡 ...
- bzoj 2565: 最长双回文串 manacher算法
2565: 最长双回文串 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem. ...
- 谈谈我对Manacher算法的理解
Manacher算法其实是求字符串里面最长的回文. ①在学习该算法前,我们应该知道回文的定义:顺序读取回文和逆序读取回文得到的结果是一样的,如:abba,aba. 那么我们不难想到,在判断一个字符串s ...
最新文章
- 监控录像帮忙找回医院被偷的女婴
- core控制器属性注入的用处_了解ASP.NET Core 依赖注入,看这篇就够了
- 华为三层交换机路由配置案例_{华为HCNP-RS}三层交换机的配置实例
- 简单看java异常栈
- java 基本类型 引用_java中 引用类型 和 基本类型 有何区别?
- SSIS hang with unhandle exception
- 柱底反力求和lisp软件_AutoLISP 基础——认识自定义函数
- LINUX下载编译nasm
- AI人工智能服务器安装说明书,AI人工智能电脑配置及服务器双显卡的安装总结...
- 卡王。卡皇一个不为人知的密秘.必看(转)
- android—AOSP、AOKP、CM的区别
- 图像处理中的一阶偏导数和二阶偏导数
- JavaScript学习第十九天
- R语言文本挖掘展示:画词云图
- 分享湖南软大自动健康打卡思路
- 全民热衷“合成大西瓜”,游戏外挂上热搜,不愧是程序员!
- 安装windows远程桌面服务器,如何安装应用,以便在 Windows Server 远程桌面服务中使用...
- iOS应用架构谈 网络层设计方案
- Gulp.js—比Grunt更易用的前端构建工具-前端自动化
- laydate控件选择类型