【算法】最长回文子串 longest palindrome substring
对于字符串S, 要找到它最长的回文子串,能想到的最暴力方法,应该是对于每个元素i-th都向左向右对称搜索,最后用一个数组span 记录下相对应元素i-th为中心的回文子串长度。
那么问题来了:
1. 这样的方法,对于奇回文子串和偶回文子串的处理不一样,比如所“acbca” 和“acbbca”
2. 计算冗余,e.g. ”sscssabcccchccccba“中, 自左向右遍历计算的话,会发现, ”abcccchccccba“是对称的,而这个回文字符串里又左右对称分别包含了两个回文子字符”cccc“和”cccc“, 在对第二个”cccc“字符串遍历的时候,其实可以利用到”abcccchccccba“的对称性来直接赋值,而不用再次计算
于是,引出了Manacher's 算法:
1. 为了可以对奇偶回文字符串不加区分地处理,对输入字符串增加边界元素(输入字符串S长度为N -> S2长度为2*N+1):e.g. ”aabbbcc“ -> "#a#a#b#b#b#c#c#" , ”aabbcc“ -> "#a#a#b#b#c#c#"
2. 对于S2字符串,自左向右,每个字符逐个计算和处理
1)用span[maxInputStringLength*2+1]数组来记录每个元素i-th为中心的回文字符串长度 : 初始化 span[0] = 0
2)用center 和 rightBoundary 来记录上一个已知的回文字符串中心index和最右边界index :初始化 center = 0, rightBoundary = 0
3)用 i 表示当前处理的元素, i2 表示 以 center 为中心的 center左侧 i 对称 元素下标 : i2 = center - (i - center)= center * 2 - i
4)加上已知的回文子串信息之后,假设已经处理了S2[0, i-1]范围的元素,那么已知的回文子串中心center 必然属于[0, i-1]区间, 但是对于rightBoundary和i的关系可以有三种情况:
a)当前处理的元素(index = i)以 center为中心,对称的元素(index = i2)上有,span[i2] < rightBoundary - i - 1, 表示i2点的回文字符串最左端不会超过leftBoundary的长度,利用了已知的回文字符串信息辅助说明,当前以i为中心的回文字符串将和i2完全对称,span[i] = span[i2]
b)当前处理的元素(index = i)以 center为中心,对称的元素(index = i2)上有,span[i2] >= rightBoundary - i - 1, 表示 i2 点的回文字符串最左端已经超过了leftBoundary的范围,不能利用已知回文字符串直接赋值,但还是可以利用对称性,使得对称搜索从rightBoundary处开始,这样可以减少计算
c)当前处理的元素(index = i)并不在已知回文串的记录范文内,那么久没有辅助信息,需要从i元素的左右对称搜索,得到span[i]的值
5)最后要更新center和rightBoundary的值,使得已知回文字符串的覆盖范围右移,这样可以持续辅助搜索
const int maxStringLength = ; string longestPalindrome(string s) { if (s.empty()) return ""; ///add boundary
string s2;
for (int i = ; i < s.size(); i++) {
s2.push_back('#');
s2.push_back(s[i]);
}
s2.push_back('#'); /// setting
int span[maxStringLength] = {};
span[] = ; // init the first element's length of palindrome
int center = , rightBoundary = ;
int left = , right = ; ///traverse
for (int i = ; i < s2.size(); i++) {
if (i <= rightBoundary) {
int i2 = center * - i;// center - (i - center)
if (span[i2] < (rightBoundary - i - )) {
span[i] = span[i2];
left = -;
}
else {
span[i] = rightBoundary - i;
right = rightBoundary + ;
left = i * - right; //i - (right - i)
}
}
else {
span[i] = ;
left = i - ;
right = i + ;
} while (left >= && right < s2.size() && s2[left] == s2[right]) {
span[i] ++;
left--;
right++;
} if ((i + span[i]) > rightBoundary) {
center = i;
rightBoundary = i + span[i];
}
} /// find the max span length
int maxSubstringCenter = , maxSubstringLen = ;
for (int i = ; i < s2.size(); i++) {
if (span[i] > maxSubstringLen) {
maxSubstringLen = span[i];
maxSubstringCenter = i;
}
} /// remove boundary '#' from substring
string result;
for (int i = maxSubstringCenter - maxSubstringLen; i <= maxSubstringCenter + maxSubstringLen; i++) {
if (s2[i] != '#')
result.push_back(s2[i]);
} return result;
}
【算法】最长回文子串 longest palindrome substring的更多相关文章
- [译]最长回文子串(Longest Palindromic Substring) Part I
[译]最长回文子串(Longest Palindromic Substring) Part I 英文原文链接在(http://leetcode.com/2011/11/longest-palindro ...
- 领扣-5 最长回文子串 Longest Palindromic Substring MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- [译+改]最长回文子串(Longest Palindromic Substring) Part II
[译+改]最长回文子串(Longest Palindromic Substring) Part II 原文链接在http://leetcode.com/2011/11/longest-palindro ...
- 最长回文子串(Longest Palindromic Substring)-DP问题
问题描述: 给定一个字符串S,找出它的最大的回文子串,你可以假设字符串的最大长度是1000,而且存在唯一的最长回文子串 . 思路分析: 动态规划的思路:dp[i][j] 表示的是 从i 到 j 的字串 ...
- [Swift]LeetCode5. 最长回文子串 | Longest Palindromic Substring
Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...
- LeetCode.5-最长回文子串(Longest Palindromic Substring)
这是悦乐书的第342次更新,第366篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Medium级别的第3题(顺位题号是5).给定一个字符串s,找到s中最长的回文子字符串. 您可以假设s ...
- Manacher算法----最长回文子串
题目描述 给定一个字符串,求它的最长回文子串的长度. 分析与解法 最容易想到的办法是枚举所有的子串,分别判断其是否为回文.这个思路初看起来是正确的,但却做了很多无用功,如果一个长的子串包含另一个短一些 ...
- Manacher算法——最长回文子串
一.相关介绍 最长回文子串 s="abcd", 最长回文长度为 1,即a或b或c或d s="ababa", 最长回文长度为 5,即ababa s="a ...
- [Swift]LeetCode409. 最长回文串 | Longest Palindrome
Given a string which consists of lowercase or uppercase letters, find the length of the longest pali ...
随机推荐
- EOJ Monthly 2018.4 (E.小迷妹在哪儿(贪心&排序&背包)
ultmaster 男神和小迷妹们玩起了捉迷藏的游戏. 小迷妹们都希望自己被 ultmaster 男神发现,因此她们都把自己位置告诉了 ultmaster 男神,因此 ultmaster 男神知道了自 ...
- 「ZJOI2008」「LuoguP2590」树的统计(树链剖分
题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...
- 洛谷P1290 欧几里德的游戏
题目:https://www.luogu.org/problemnew/show/P1290 只要出现n>=2*m,就可以每次把较大的数控制在较小的数的一倍与二倍之间,则控制了对方的走法: 每次 ...
- apple-touch-startup-image 制作iphone web应用程序的启动画面
为ipad制作web应用程序的启动画面时发现个问题,只能显示竖屏图,横屏图出不来,如下: 首先页面头部里要加入(这个是APP启动画面图片,如果不设置,启动画面就是白屏,图片像素就是手机全屏的像素) & ...
- Codeforces 550B 【暴力】
题意: 有n个数字, 要求在这n个数中选出至少两个数字, 使得它们的和在L,R之间,并且最大的与最小的差值要不小于x 思路: 撒比了啊... 根据状态的话一共也就是2^15-直接暴力,二进制的小魅力还 ...
- hdoj1150(最小点覆盖)
题意: 两台机器,A台机器有N种模式,B台机器有M种不同的模式,初始模式都是0 以及K个需要运行的任务(i,x,y),在A台机器是x模式,在B台机器是y模式. 请合理为每个任务安排一台机器并合理安排顺 ...
- mysql关于时间函数的应用
1.获取今天的数据 date_format(publishtime, '%Y-%m-%d')= date_format(now(), '%Y-%m-%d') 2.获取今天和明天的数据 server.b ...
- 分析spring aop的源码实现
AOP就是面向切面编程,我们可以从几个层面来实现AOP. 在编译器修改源代码,在运行期字节码加载前修改字节码或字节码加载后动态创建代理类的字节码,以下是各种实现机制的比较. spring AOP是Sp ...
- Mybatis 未设置主键映射报错;Cause: java.sql.SQLSyntaxErrorException: Unknown column 'system_id' in 'field list'
使用MyBatis的时候,主键的字段建议绑定在Bean的属性上面, import javax.persistence.*; public class User { @Id @Column(name = ...
- BZOJ4653(区间离散化+线段树+决策单调尺取)
写得很好的题解 一眼过去很像是:排序,然后从前向后扫,有这个区间时插到树里,过去以后再删除.然后事实也是这样做的…… 具体起来: 1.如果考虑暴力的话,一种想法是枚举左端和右端要选取的区间(如果我们按 ...