最长回文子串问题 O(n)算法 manacher URAL1297 HDU3068
先来看一道简单的题,ural1297 给定一个1000长度的字符串,求最长回文子串。
看起来很Naive,乱搞一下,O(n^2)都可以解决。
再来看这个题 HDU3068 120个110000长度的字符串,是不是感觉有点困难了?据说后缀数组也要TLE
给出一个O(n)的解决方案 manacher算法 很有趣的利用了回文子串的性质,进行递推更新。
转载自http://blog.csdn.net/ggggiqnypgjg/article/details/6645824
这里,我介绍一下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开始的)
好,到这里,我们可以先贴一份代码了。
|
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm> using namespace std; const int maxn=310000+1; int find_palindrome(char str[],int sym[],int len[],int n)//需要对数组sym在外部进行初始化
{
int maxl=1;
sym[0]=1;
for(int i=1,j=0;i<(n<<1)-1;++i)
{
int p=i>>1,q=i-p,r=((j+1)>>1)+sym[j]-1;
sym[i]=r<q ? 0:min(r-q+1,sym[(j<<1)-i]);
while(p>sym[i]-1&&q+sym[i]<n&&str[p-sym[i]]==str[q+sym[i]])
++sym[i];
if(q+sym[i]-1>r)
j=i;
}
for(int i=0;i<n;i++)
len[i]=1;
for(int i=0;i<n;i++)
{
int ls=i-sym[i*2]+1;
if(ls<0)continue;
len[ls]=max(len[ls],sym[i*2]*2-1);
maxl=max(maxl,len[ls]);
if(sym[i*2+1]==0)continue;
ls=i-sym[i*2+1]+1;
if(ls<0)continue;
len[ls]=max(len[ls],sym[i*2+1]*2);
maxl=max(maxl,len[ls]);
}
return maxl;
} char str[maxn];
int len[maxn*2],ans[maxn];
int main()
{ios::sync_with_stdio(false);
freopen("t.txt","r",stdin); while(cin>>str)
{ memset(len,0,sizeof(len));
cout<<find_palindrome(str,len,ans,strlen(str))<<endl;
memset(str,0,sizeof(str)); }
return 0;
}
最长回文子串问题 O(n)算法 manacher URAL1297 HDU3068的更多相关文章
- 【转】最长回文子串的O(n)的Manacher算法
Manacher算法 首先:大家都知道什么叫回文串吧,这个算法要解决的就是一个字符串中最长的回文子串有多长.这个算法可以在O(n)的时间复杂度内既线性时间复杂度的情况下,求出以每个字符为中心的最长回文 ...
- Leetcode(5)-最长回文子串(包含动态规划以及Manacher算法)
给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为1000. 示例 1: 输入: "babad" 输出: "bab" 注意: &quo ...
- 最长回文子串-LeetCode 5 Longest Palindromic Substring
题目描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...
- 最长回文子串(Longest Palindromic Substring)
这算是一道经典的题目了,最长回文子串问题是在一个字符串中求得满足回文子串条件的最长的那一个.常见的解题方法有三种: (1)暴力枚举法,以每个元素为中心同时向左和向右出发,复杂度O(n^2): (2)动 ...
- lintcode最长回文子串(Manacher算法)
题目来自lintcode, 链接:http://www.lintcode.com/zh-cn/problem/longest-palindromic-substring/ 最长回文子串 给出一个字符串 ...
- 1089 最长回文子串 V2(Manacher算法)
1089 最长回文子串 V2(Manacher算法) 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 回文串是指aba.abba.cccbccc.aaaa ...
- 51nod1089(最长回文子串之manacher算法)
题目链接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1089 题意:中文题诶~ 思路: 我前面做的那道回文子串的题 ...
- 求最长回文子串:Manacher算法
主要学习自:http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html 问题描述:回文字符串就是左右 ...
- [译+改]最长回文子串(Longest Palindromic Substring) Part II
[译+改]最长回文子串(Longest Palindromic Substring) Part II 原文链接在http://leetcode.com/2011/11/longest-palindro ...
随机推荐
- python3.x Day5 面向对象
类:类是指:对具有相同属性的事物的抽象.蓝图.原型.在类中定义了这些事物都具备的属性和共同的方法. 对象:一个对象就是一个类实例化以后的实例,一个类必须经过实例化后才能在程序中被使用,一个类可以实例化 ...
- *** 红包书用法 及 ubuntu全局配置
使用教程 http://go.wasai.org/sswiki https://home.maysoul.com/wiki/doku.php?id=shadowsocks ubuntu使用教程 htt ...
- HTML基础知识 table中 th,td,tr
https://www.2cto.com/kf/201711/701872.html table是一个布局神器,之前看过很多代码,都是用table布局的.但是,我在学习的过程中,发现table有很迷的 ...
- jQuery学习之------html()、text()和val()
jQuery学习之------html().text()和val() .html(),.text()和.val()的差异总结: (来源:慕课网) .html(),.text(),.val()三种方法 ...
- Leetcode 174.地下城游戏
地下城游戏 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主. ...
- 【HDOJ6118】度度熊的交易计划(费用流)
题意: 度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题: 喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区. 由于生产能力的区别,第i个片区能够花费a[i]元生产1个 ...
- 【BZOJ2142】礼物(扩展lucas定理,中国剩余定理合并方程)
题意:有n件礼物,m个人,每个人分别需要w[i]件礼物,求分礼物的不同方案数 mod P 提示:设P=p1^c1 * p2^c2 * p3^c3 * … *pt ^ ct,pi为质数. 1≤n≤10^ ...
- 无权二分图最大匹配 HDU2063 匈牙利算法 || Hopcroft-Karp
参考两篇比较好的博客 http://www.renfei.org/blog/bipartite-matching.html http://blog.csdn.net/thundermrbird/art ...
- Windows堆思维导图--Windows pro sp3
http://bbs.pediy.com/showthread.php?p=1445192#post1445192
- python: filter, map, reduce, lambda
filter built-in function filter(f,sequence) filter can apply the function f to each element of seque ...