这里,我介绍一下O(n)回文串处理的一种方法。Manacher算法.
原文地址:
http://zhuhongcheng.wordpress.com/2009/08/02/a-simple-linear-time-algorithm-for-finding-longest-palindrome-sub-string/
    其实原文说得是比较清楚的,只是英文的,我这里写一份中文的吧。
    首先:大家都知道什么叫回文串吧,这个算法要解决的就是一个字符串中最长的回文子串有多长。这个算法可以在O(n)的时间复杂度内既线性时间复杂度的情况下,求出以每个字符为中心的最长回文有多长,
    这个算法有一个很巧妙的地方,它把奇数的回文串和偶数的回文串统一起来考虑了。这一点一直是在做回文串问题中时比较烦的地方。这个算法还有一个很好的地方就是充分利用了字符匹配的特殊性,避免了大量不必要的重复匹配。
    算法大致过程是这样。先在每两个相邻字符中间插入一个分隔符,当然这个分隔符要在原串中没有出现过。一般可以用‘#’分隔。这样就非常巧妙的将奇数长度回文串与偶数长度回文串统一起来考虑了(见下面的一个例子,回文串长度全为奇数了),然后用一个辅助数组P记录以每个字符为中心的最长回文串的信息。P[id]记录的是以字符str[id]为中心的最长回文串,当以str[id]为第一个字符,这个最长回文串向右延伸了P[id]个字符。
    原串:    w aa bwsw f d
    新串:   # w # a # a # b # w # s # w # f # d #
辅助数组P:  1 2 1 2 3 2 1 2 1 2 1 4 1 2 1 2 1 2 1
    这里有一个很好的性质,P[id]-1就是该回文子串在原串中的长度(包括‘#’)。如果这里不是特别清楚,可以自己拿出纸来画一画,自己体会体会。当然这里可能每个人写法不尽相同,不过我想大致思路应该是一样的吧。
    好,我们继续。现在的关键问题就在于怎么在O(n)时间复杂度内求出P数组了。只要把这个P数组求出来,最长回文子串就可以直接扫一遍得出来了。
    由于这个算法是线性从前往后扫的。那么当我们准备求P[i]的时候,i以前的P[j]我们是已经得到了的。我们用mx记在i之前的回文串中,延伸至最右端的位置。同时用id这个变量记下取得这个最优mx时的id值。(注:为了防止字符比较的时候越界,我在这个加了‘#’的字符串之前还加了另一个特殊字符‘$’,故我的新串下标是从1开始的)
好,到这里,我们可以先贴一份代码了。

    void pk()
{
int i;
int mx = ;
int id;
for(i=; i<n; i++)
{
if( mx > i )
p[i] = MIN( p[*id-i], mx-i );
else
p[i] = ;
for(; str[i+p[i]] == str[i-p[i]]; p[i]++)
;
if( p[i] + i > mx )
{
mx = p[i] + i;
id = i;
}
}
}

代码是不是很短啊,而且相当好写。很方便吧,还记得我上面说的这个算法避免了很多不必要的重复匹配吧。这是什么意思呢,其实这就是一句代码。

 
if( mx > i )
    p[i]= MIN( p[2*id-i], mx-i );
 
就是当前面比较的最远长度mx>i的时候,P[i]有一个最小值。这个算法的核心思想就在这里,为什么P数组满足这样一个性质呢?
   (下面的部分为图片形式)
    看完这个算法,你有可能会觉得这种算法在哪会用到呢?其实回文串后缀数组也可以做。只是复杂度是O(n log n)的,而且一般情况下也不会刻意去卡一个log n的算法。可正好hdu就有这么一题,你用后缀数组写怎么都得T(当然应该是我写得太烂了)。不信的话大家也可以去试试这题。

http://acm.hdu.edu.cn/showproblem.php?pid=3068
    另外,顺便附一份AC代码。
        http://acm.hust.edu.cn:8080/judge/problem/viewSource.action?id=140283

[转]O(n)回文子串算法 Manacher算法的更多相关文章

  1. Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法)

    Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法) Given a string s, find the longest pal ...

  2. 最长回文子串的Manacher算法

    对于一个比较长的字符串,O(n^2)的时间复杂度是难以接受的.Can we do better? 先来看看解法2存在的缺陷. 1) 由于回文串长度的奇偶性造成了不同性质的对称轴位置,解法2要对两种情况 ...

  3. 51nod1089(最长回文子串之manacher算法)

    题目链接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1089 题意:中文题诶~ 思路: 我前面做的那道回文子串的题 ...

  4. 求最长回文子串:Manacher算法

    主要学习自:http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html 问题描述:回文字符串就是左右 ...

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

    回文字符串,想必大家不会不熟悉吧? 回文串会求的吧?暴力一遍O(n^2)很简单,但当字符长度很长时便会TLE,简单,hash+二分搞定,其复杂度约为O(nlogn), 而Manacher算法能够在线性 ...

  6. 计算字符串的最长回文子串 :Manacher算法介绍

    转自: http://www.open-open.com/lib/view/open1419150233417.html Manacher算法 在介绍算法之前,首先介绍一下什么是回文串,所谓回文串,简 ...

  7. 51Nod 1089 最长回文子串 V2 —— Manacher算法

    题目链接:https://vjudge.net/problem/51Nod-1089 1089 最长回文子串 V2(Manacher算法) 基准时间限制:1 秒 空间限制:131072 KB 分值:  ...

  8. 51 Nod 1089 最长回文子串(Manacher算法)

    1089 最长回文子串 V2(Manacher算法)  基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 回文串是指aba.abba.cccbccc.aaa ...

  9. 图解最长回文子串「Manacher 算法」,基础思路感性上的解析

    问题描述: 给你一个字符串 s,找到 s 中最长的回文子串. 链接:https://leetcode-cn.com/problems/longest-palindromic-substring 「Ma ...

  10. hihocoder #1032 : 最长回文子串【 manacher算法实现 】

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

随机推荐

  1. Code Hard or Go Home

    介绍Webkit的渊源  http://hypercritical.co/2013/04/12/code-hard-or-go-home

  2. Loadrunner脚本之C语言文件处理函数

    一.打开文件 打开文件使用库函数中的fopen函数.fopen函数会为要打开的文件新建一个流,然后返回一个指向file型对象的指针,该file型对象中保存了控制这个流所需要的信息. fp=fopen( ...

  3. ajax给全局变量赋值问题

    ajax给全局变量赋值问题 今天在做项目时,遇到了一个问题.我用的是ajax,要在$.ajax({里面给一个全局变量赋值,结果死活赋值不上,纠结了好半天,后来上网查了查,才知道,ajax默认是异步请求 ...

  4. IoC(控制反转)

    在传统的编程中,我们通过内部代码来控制组件之间的关系,但是这种实现方式,容易造成组件之间的高耦合.IoC能够很好地解决这个问题,它将组件间的关系从程序内部上提到外部容器来管理.IoC的核心目标是通过简 ...

  5. linux c下mysql编程样例

    /* ============================================================================ Name : mysql1.c Auth ...

  6. air手势代码

    //下列2句谁放上面谁生效要么触控生效,要么手势生效 Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT; Multitouch.inputM ...

  7. 【Maven】Maven下载源码和Javadoc的方法

    1:Maven命令下载源码和javadocs 当在IDE中使用Maven时如果想要看引用的jar包中类的源码和javadoc需要通过maven命令下载这些源码,然后再进行引入,通过mvn命令能够容易的 ...

  8. oracel 导入导出

    一.导出模式(三种模式)及命令格式 1. 全库模式 exp 用户名/密码@网络服务名 full=y file=路径\文件名.dmp log=路径\文件名.log 2. 用户模式(一般情况下采用此模式) ...

  9. [iOS微博项目 - 3.3] - 封装网络请求

    github: https://github.com/hellovoidworld/HVWWeibo   A.封装网络请求 1.需求 为了避免代码冗余和对于AFN框架的多处使用导致耦合性太强,所以把网 ...

  10. AJAX小练习,防止以后忘记

    <div id="content"> <input id="btnShow" type="button" value=&q ...