manacher java_最大回文子串(Manacher算法)
1.Manacher算法
首先说明一下,Manacher算法能够使得在O(n)的时间复杂度下找到最长的回文子串。
(1).Manacher算法的概述
Manacher算法只能解决长度为奇数的字符串,所以Manacher算法利用了一个比较巧妙的方法来同时解决长度为奇数或者偶数的字符串。Manacher算法通过转换字符串来实现的,例如:原来的字符串:abc,经过转换得到:#a#b#c#,这样原来的字符串长度不管是奇数还是偶数,最终转换都能够得到一个长度为奇数的字符串。
其次,Manacher算法通常还需要一个数组(我们假设是,len数组)来记录每一个字符在原字符串中的回文字符串的最大长度,其实实际上是,该字符在原来的字符串中得到的最长回文字符串的一半长度。
例如:aba,经过转换得到:#a#b#a#,b能得到的最长回文字符串是:#a#b#a#,我们假设b的下标是i,得到的最长字符串的第一个字符下标是left,最后一个字符的下标是right那么b对应的值是:right - i + 1;
同时,我们还能知道的是,i对应的字符得到的最大回文子串长度是:len[i] - 1,例如:上面的例子,b的下标是3,所以len[3] = 4,那么b对应的回文字符串aba,长度恰好是len[3] - 1 = 3。这个是为什么呢?我们假设原来的字符串为oldString(没有经过转换的),转换过后的字符串为newString,假设oldString长度为length,那么newString的长度就为2 * length + 1,所以得到的字符串长度肯定为奇数。对于newString中的第i个字符对应的回文字符串,长度肯定为2 * len[i] - 1(这个你们可以简单的去举例子测试一下),同时,经过观察得知,2 * len[i] - 1个字符中,肯定有len[i]个是#,其余的才是正常的符号,因为在所有的回文字符串中#的个数总是与其他符号的个数相差为1。
(2).len数组的计算
首先,我们从左往右计算len[i],当我们计算len[i]时,len[j]已经计算完毕(0 < j < i)。
我们假设,在已经计算了的字符当中取得最长回文子串的右端点的最大值(该回文字符串不一定是最长的回文字符串,只是要求该回文字符串右端下标最大),假设最大值rightIndex,并且设置该回文子串中心的位置是centerIndex,那么分为两种情况:
A.i < rightIndex
我们假设以centerIndex为中心,与i对应的是j。如图:
我们知道的是,以centerIndex为中心,回文字符串能达到rightIndex,那么此时有分为两种情况:
如果i + len[j] < rightIndex,也就是说,以j为中心的回文字符串在以centerInde为中心的回文字符串内部,此时可以得到以j为中心的回文字符串与以i为中心的回文字符串是相同的,为什么呢?因为他们在以centerIndex为中心的回文字符串的内部。所以可以得到的是,len[i] = len[j]。
如果i + len[j] >= rightIndex的话,也就是说,以i为中心的回文字符串有一部分在以centerIndex为中心的回文字符串的外部,此时外部这一部分需要我们一个一个的计算。
B.i > rightIndex
如果i > rightIndex的话,那就说明,以i为中心的回文字符串一点都没有匹配。所以需要我们一个一个的匹配了。
var longestPalindrome = function(s) {
if (!s) return ''
const new_s = '#' + s.split('').join('#') + '#' // 把字符串处理成奇数个 let rightIndex = 0 // 右边界 let centerIndex = 0 // 中心 let maxlen = 0 // 最大回文长度 let index = 0 //最大回文中心 let len = []
for (let i = 0; i < new_s.length; i++) {
if (i < rightIndex) {
len[i] = Math.min(rightIndex - i, len[2 * centerIndex - i])
} else {
len[i] = 1
}
while (i - len[i] >=0 && i + len[i] <= new_s.length && new_s[i - len[i]] === new_s[i + len[i]]) {
len[i]++
}
// 更新右边界和中心 if (i + len[i] > rightIndex) {
centerIndex = i
rightIndex = i + len[i]
}
// 当前回文长度大于最大长度---替换 if (len[i] > maxlen) {
maxlen = len[i]
index = i
}
}
return new_s.substring(index - maxlen + 1, index + maxlen).replace(/#/g, '')
};
manacher java_最大回文子串(Manacher算法)相关推荐
- HihoCode1032 最长回文子串 manacher算法
求最长回文子串的算法比较经典的是manacher算法 转载自这里 首先,说明一下用到的数组和其他参数的含义: (1)p[i] : 以字符串中下标为的字符为中心的回文子串半径长度: 例如:abaa字符串 ...
- 回文字符串—回文子串—Manacher算法
leetcode地址:5. 最长回文子串 解答参考:动态规划.中心扩散.Manacher 算法 问题描述: 给你一个字符串 s,找到 s 中最长的回文子串.比如给定字符串s = "babad ...
- lintcode最长回文子串(Manacher算法)
题目来自lintcode, 链接:http://www.lintcode.com/zh-cn/problem/longest-palindromic-substring/ 最长回文子串 给出一个字符串 ...
- 求解最长回文子串----Manacher 算法
最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 如果一个字符串正着读和反着读是一样的,那么我们称之为回文串.例如:abba.aaaa.abvcba.123321等 暴力法:遍历字符串的所有 ...
- 最长回文子串——Manacher 算法
0. 问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 如果一个字符串正着读和反着读是一样的,那它就是回文串.下面是一些回文串的实例: 12321 a aba abba aaaa ...
- 最长回文子串manacher算法模板
#1032 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在 ...
- 【字符串】最长回文子串 ( 蛮力算法 )
文章目录 一.回文串.子串.子序列 二.最长回文子串 1.蛮力算法 2.时间复杂度最优方案 一.回文串.子串.子序列 " 回文串 ( Palindrome ) " 是 正反都一样的 ...
- 最长回文子串 -- 马拉松算法
百度了好长时间,看了很多篇博客才稍微看懂,所以自己写篇博客加深一下映像,并且写的尽量详细一些 希望大家能够只这篇博客就能看懂,能少走些弯路 马拉松算法 1.添加特殊字符 通常情况下,对于一个字符串,需 ...
- 【字符串】最长回文子串 ( 动态规划算法 ) ★
文章目录 一.回文串.子串.子序列 二.最长回文子串 1.动态规划算法 2.动态规划算法代码示例 一.回文串.子串.子序列 " 回文串 ( Palindrome ) " 是 正反都 ...
最新文章
- 我们用Windows官方跑了跑Linux GUI应用程序,不愧是“胶水操作系统”
- 基本数据类型和引用数据类型作为参数时候的问题
- Hbuilder 常用快捷键汇总
- 进阶学习(4.2) JVM 常用配置参数, GC 参数
- Redis 是怎么实现 “附近的人” 的?
- 1.在Linux下如何使用软盘、光盘以及DOS等非Linux分区
- 理解Joomla!模板
- On branch master nothing to commit, working tree clean
- Hibernate初学之CURD
- Centos7安装图形桌面
- java中使用nextLine(); 没有输入就自动跳过的问题?
- php websocket ipv6,原生socket支持ipv6
- informix 如何下载
- SpringAop实现原理
- 计算机cpu后面字母代表什么意思,英特尔CPU型号中最后的字母什么意思?如有不懂欢迎驻足停留...
- c++中的继承机制(Derived Classes)
- 用无线插板控制RC(远程遥控)小车
- limbo运行veket linux,Veket Linux使用(非常适合老电脑的系统)
- 游戏美术都受到了什么绘画风格的影响
- python手机触屏代码_JS移动客户端--触屏滑动事件及js手机拖拽效果