回文字符串,想必大家不会不熟悉吧?

回文串会求的吧?暴力一遍O(n^2)很简单,但当字符长度很长时便会TLE,简单,hash+二分搞定,其复杂度约为O(nlogn), 而Manacher算法能够在线性的时间内处理出最长回文子串。

让我们来看道题:http://acm.hdu.edu.cn/showproblem.php?pid=3068

这个算法的巧妙之处,便是把奇数的回文串和偶数的回文串统一起来考虑了。这一点一直是在做回文串问题中时比较烦的地方。这个算法还有一个很好的地方就是充分利用了字符匹配的特殊性,避免了大量不必要的重复匹配。那怎么去实现呢?

我们要求字符串s中最长的回文子串

Manacher重新构造了一个新数组,在每两个字符中间插入一个'#',如下图:

我们很容易发现,如果出现这种情况(如下图)在处理第三个字符('#')市,会发现扫到左侧时候可能会出现越界

为了避免索引数超出数组边界值做字符比较,可以在处理过的字符串的第一个位置(索引为0的位置)加入一个区分字符,笔者喜欢用'@'。

上图便是处理过的样子。(编号表示数组位数,3表示是s[3]的字符)

我们现在用p[i]数组表示以字符s[i]为中心的回文半径(如p[3] = 1)。

我们很容易发现最长子序列的长度刚好是(p[i] - 1)。

那么我们怎么来求p[i]数组呢?

步骤如下:

当处理到[i]的时候,我们去找0-i中是否存在一个数(设为id)使得p[id] + id > i,设mx = p[id] + id。

如上图,由于红的字符串是回文字符串,所以关于j对称的回文子串和关于i对称的回文子串是完全一样的(图中两段绿色的线条),而满足mx-i>P[j]时说明此时j的回文子串半径小于j到mx关于j对称的左端点的差,此时可以初始化P[i]=P[j]。但如果绿色部分超出id的回文串呢?

如下图:

紫色表示以j为中心的回文串超出以id为中心的回文半径的部分(即图中红色部分)由于红的字符串是回文字符串,所以关于j对称的回文子串和关于i对称的在mx和mx的对称点之间的回文子串是完全一样的(图中两段绿色的线条),而满足mx-i<=P[j]时说明此时j的回文子串半径大于或等于j到mx关于j对称的左端点的差,此时可以初始化P[i]=mx-i,超出部分只能一个个判断。再对P[i]的回文子串半径进行进一步的增大。(以上两图均取自参考论文)

综上所述初始化p[i] = min(p[j], mx - i);

对于超出回文字符串部分(即红色部分,我们只能一个一个的去判断)

即while(s[i + p[i]] == s[i - p[i]])p[i] += 1;

当mx <= i 的时候我们只能将p[i] 初始化为1(对于它都是未知的,只能通过一位一位去比较)。

附上总代码:

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = + ; char s[N]; int p[N]; int n, id, mx; void work(){
id = mx = ;
int ans = ;
n = strlen(s);
for(int i = n; i >= ; i --){
s[ * i + ] = s[i];
s[ * i + ] = '#';
}
s[] = '@';
p[] = ;
for(int i = ; i < * n + ; i ++){
if(mx > i)p[i] = min(p[ * id - i], mx - i);
else p[i] = ;
while(s[i + p[i]] == s[i - p[i]]) p[i] += ;
if(mx < p[i] + i){
id = i;
mx = p[i] + i;
}
ans = max(ans, p[i] - );
}
printf("%d\n", ans);
} int main(){
while(scanf("%s", s) == )work();
return ;
}

参考资料:http://blog.csdn.net/pi9nc/article/details/9251455

最长回文子串(Manacher算法)的更多相关文章

  1. 九度OJ 1528 最长回文子串 -- Manacher算法

    题目地址:http://ac.jobdu.com/problem.php?pid=1528 题目描述: 回文串就是一个正读和反读都一样的字符串,比如"level"或者"n ...

  2. lintcode最长回文子串(Manacher算法)

    题目来自lintcode, 链接:http://www.lintcode.com/zh-cn/problem/longest-palindromic-substring/ 最长回文子串 给出一个字符串 ...

  3. 最长回文子串—Manacher 算法 及 python实现

    最长回文子串问题:给定一个字符串,求它的最长回文子串长度.如果一个字符串正着读和反着读是一样的,那它就是回文串.   给定一个字符串,求它最长的回文子串长度,例如输入字符串'35534321',它的最 ...

  4. hihocoder #1032 : 最长回文子串 Manacher算法

    题目链接: https://hihocoder.com/problemset/problem/1032?sid=868170 最长回文子串 时间限制:1000ms内存限制:64MB 问题描述 小Hi和 ...

  5. 5. Longest Palindromic Substring(最长回文子串 manacher 算法/ DP动态规划)

    Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...

  6. HiHo 1032 最长回文子串 (Manacher算法求解)

    /** * 求解最长回文字串,Manacher算法o(n)求解最长回文子串问题 **/ #include<cstdio> #include<cstdlib> #include& ...

  7. hihoCoder #1032 : 最长回文子串 [ Manacher算法--O(n)回文子串算法 ]

    传送门 #1032 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相 ...

  8. 51nod1089 最长回文子串 manacher算法

    0. 问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 如果一个字符串正着读和反着读是一样的,那它就是回文串.下面是一些回文串的实例: 12321 a aba abba aaaa ...

  9. 最长回文子串Manacher算法模板

    Manacher算法能够在O(N)的时间复杂度内得到一个字符串以任意位置为中心的回文子串.其算法的基本原理就是利用已知回文串的左半部分来推导右半部分. 首先,在字符串s中,用rad[i]表示第i个字符 ...

  10. 求最长回文子串——Manacher算法

    回文串包括奇数长的和偶数长的,一般求的时候都要分情况讨论,这个算法做了个简单的处理把奇偶情况统一了.算法的基本思路是这样的,把原串每个字符中间用一个串中没出现过的字符分隔开来(统一奇偶),用一个数组p ...

随机推荐

  1. (ios7) 解决Ios7中,Navigatebar 显示在主View中,和ios6 不一致问题

    在ios 7 系统中 NavigateBar 显示在主View中 ,Ios6 不在主View中,导致后台代码的方式编写View不一致 解决方法: 在ViewControl的viewDidLoad 方法 ...

  2. cocos2d-x之事件传递

    bool HelloWorld::init() { if ( !Layer::init() ) { return false; } Size size=Director::getInstance()- ...

  3. QQ JS省市区三级联动

    如下图: 首先写一个静态的页面: <!DOCTYPE html> <html> <head> <title>QQ JS省市区三级联动</title ...

  4. Github学习之路-初出茅庐,接触Github,了解Github

     一.了解GitHub 作为一个在线协作网站,GitHub允许程序员们分享和协力于开源项目的工作. GitHub不仅是一个分享开源创作并与其它程序员合作的好地方,你也可以从GitHub上收到自己作品的 ...

  5. JavaScript中奇葩的假值

    通常在以下语句结构中需要判断真假 if分支语句 while循环语句 for里的第二个语句 如 if (boo) { // do something } while (boo) { // do some ...

  6. ACM竞赛高手比其他程序员水平高很多吗?

    1. ACM是一种很直接的评价程序员水平的体系 2. ACM竞赛会带来很多机遇(深造or工作),同时又是一个不小的挑战 3. 为竞赛而竞赛的事情不可取 详细点击这里

  7. table边框美化

    在<table>里面加代码就可以了. 效果1: <TABLE style="BORDER-RIGHT: #993333 3px dashed; BORDER-TOP: #9 ...

  8. Excel Sheet Column Number

    Related to question Excel Sheet Column Title Given a column title as appear in an Excel sheet, retur ...

  9. 边工作边刷题:70天一遍leetcode: day 86

    Word Pattern II 要点: 注意与I的差异,其实题不难,看到这种迷乱的,首先要想到backtrack 1:1 mapping两个条件:p in and str in, or p not i ...

  10. Blend Tree Type

    1D 只有一个参数,用于控制状态之间的切换 2D Simple Directional 2D Simple Directional   :具有方向性的动画片段,同一方向上最好不要有多个动画片段 2D ...