manacher算法求最长回文子串
一:背景
给定一个字符串,求出其最长回文子串。例如:
- s="abcd",最长回文长度为 1;
- s="ababa",最长回文长度为 5;
- s="abccb",最长回文长度为 4,即bccb。
以上问题的传统思路大概是,遍历每一个字符,以该字符为中心向两边查找。其时间复杂度为$O(n^2)$,效率很差。
1975年,一个叫Manacher的人发明了一个算法,Manacher算法(中文名:马拉车算法),该算法可以把时间复杂度提升到$O(n)$。下面来看看马拉车算法是如何工作的。
二:算法过程分析
由于回文分为偶回文(比如 bccb)和奇回文(比如 bcacb),而在处理奇偶问题上会比较繁琐,所以这里我们使用一个技巧,具体做法是:在字符串首尾,及各字符间各插入一个字符(前提这个字符未出现在串里)。
举个例子:s="abbahopxpo",转换为s_new="$#a#b#b#a#h#o#p#x#p#o#"(这里的字符 $ 只是为了防止越界,下面代码会有说明),如此,s 里起初有一个偶回文abba和一个奇回文opxpo,被转换为#a#b#b#a#和#o#p#x#p#o#,长度都转换成了奇数。
定义一个辅助数组int p[],其中p[i]表示以 i 为中心的最长回文的半径,例如:
| i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| s_new[i] | $ | # | a | # | b | # | b | # | a | # | h | # | o | # | p | # | x | # | p | # |
| p[i] | 1 | 2 | 1 | 2 | 5 | 2 | 1 | 2 | 1 | 2 | 1 | 2 | 1 | 2 | 1 | 4 | 1 | 2 | 1 |
可以看出,p[i] - 1正好是原字符串中最长回文串的长度。
接下来的重点就是求解 p 数组,如下图:
设置两个变量,mx 和 id 。mx 代表以 id 为中心的最长回文的右边界,也就是mx = id + p[id]。
假设我们现在求p[i],也就是以 i 为中心的最长回文半径,如果i < mx,如上图,那么:
if (i < mx)
p[i] = min(p[2 * id - i], mx - i);
2 * id - i为 i 关于 id 的对称点,即上图的 j 点,而p[j]表示以 j 为中心的最长回文半径,因此我们可以利用p[j]来加快查找。
三:代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
];
];
];
int Init()
{
int len = strlen(s);
s_new[] = '$';
s_new[] = '#';
;
; i < len; i++)
{
s_new[j++] = s[i];
s_new[j++] = '#';
}
s_new[j] = '\0'; // 别忘了哦
return j; // 返回 s_new 的长度
}
int Manacher()
{
int len = Init(); // 取得新字符串长度并完成向 s_new 的转换
; // 最长回文长度
int id;
;
; i < len; i++)
{
if (i < mx)
p[i] = min(p[ * id - i], mx - i); // 需搞清楚上面那张图含义, mx 和 2*id-i 的含义
else
p[i] = ;
while (s_new[i - p[i]] == s_new[i + p[i]]) // 不需边界判断,因为左有'$',右有'\0'
p[i]++;
// 我们每走一步 i,都要和 mx 比较,我们希望 mx 尽可能的远,这样才能更有机会执行 if (i < mx)这句代码,从而提高效率
if (mx < i + p[i])
{
id = i;
mx = i + p[i];
}
max_len = max(max_len, p[i] - );
}
return max_len;
}
int main()
{
while (printf("请输入字符串:\n"))
{
scanf("%s", s);
printf("最长回文长度为 %d\n\n", Manacher());
}
;
}
manacher算法求最长回文子串的更多相关文章
- Manacher算法——求最长回文子串
首先,得先了解什么是回文串.回文串就是正反读起来就是一样的,如“abcdcba”.我们要是直接采用暴力方法来查找最长回文子串,时间复杂度为O(n^3),好一点的方法是枚举每一个字符,比较较它左右距离相 ...
- Manacher算法 求 最长回文子串
1 概述(扯淡) 在了解Manacher算法之前,我们得先知道什么是回文串和子串. 回文串,就是正着看反着看都一样的字符串.比如说"abba"就是一个回文串,"abbc& ...
- Manacher算法 - 求最长回文串的利器
求最长回文串的利器 - Manacher算法 Manacher主要是用来求某个字符串的最长回文子串. 不要被manacher这个名字吓倒了,其实manacher算法很简单,也很容易理解,程序短,时间复 ...
- manacher算法求最长回文子序列
一:背景 给定一个字符串,求出其最长回文子串.例如: s="abcd",最长回文长度为 1: s="ababa",最长回文长度为 5: s="abcc ...
- 使用manacher算法解决最长回文子串问题
要解决的问题 求一个字符串最长回文子串是什么.且时间复杂度 O(N) 具体描述可参考: LeetCode_5_最长回文子串 LintCode_200_最长回文子串 暴力解法 以每个字符为中心向左右两边 ...
- hdu 3068 最长回文 (Manacher算法求最长回文串)
参考博客:Manacher算法--O(n)回文子串算法 - xuanflyer - 博客频道 - CSDN.NET 从队友那里听来的一个算法,O(N)求得每个中心延伸的回文长度.这个算法好像比较偏门, ...
- 小白月赛13 B小A的回文串 (马拉车算法求最长回文子串)
链接:https://ac.nowcoder.com/acm/contest/549/B来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...
- leetcode 5 Longest Palindromic Substring(Manacher算法求最长回文串)
应用一下manacher算法就可以O(n)求出结果了.可以参考hdu3068 substr(start,length)函数是这样用的: substr 方法 返回一个从指定位置开始,并具有指定长度的子字 ...
- Manacher算法求最长回文串模板
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> ...
随机推荐
- HDU5154拓扑排序
Harry and Magical Computer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- devDependencies 和 dependencise 的区别
在使用 npm install 安装模块或者插件的时候,在命令中可以添加俩种参数把他们写入到 pakeage.json 文件里面去: --save ( 简写 -S ) --save-dev ( 简写 ...
- 【比赛】STSRM 09
第一题 题意:n个点,每个点坐标pi属性ai,从右往左将遇到的点向左ai范围内的点消除,后继续扫描. 现可以在扫描开始前提前消除从右往左任意点,问最少消除数(提前+扫描). n,pi,ai<=1 ...
- Html5_sessionStrong和localStorage的灵活使用
谈谈这两个属性sessionStrong和localStorage是Html5新增点属性,用来记录一些数据在浏览器. 两者的区别sessionStrong存储的数据是暂时的,浏览器关掉后,存储下来的数 ...
- poj 2387 Til the Cows Come Home(dijkstra算法)
题目链接:http://poj.org/problem?id=2387 题目大意:起点一定是1,终点给出,然后求出1到所给点的最短路径. 注意的是先输入边,在输入的顶点数,不要弄反哦~~~ #incl ...
- Python-字符串处理 str.format()
Python中内置的%操作符可用于格式化字符串操作,控制字符串的呈现格式.Python中还有其他的格式化字符串的方式,但%操作符的使用是最方便的. 另外python还有一个更强大的字符串处理函数 st ...
- 原始套接字&&数据链路层访问
1. 原始套接字能力: (1) 进程可以读写ICMP,IGMP等分组,如ping程序: (2) 进程可以读写内核不处理协议字段的ipv4数据报:如OSPF等: (3) 进程可以使用IP_HDRINCL ...
- 简单的自动化运维工具(shell+except+whiptail+功能模块化函数+循环)
简单的自动化运维工具(shell+except+whiptail+功能模块化函数+循环) http://www.cnblogs.com/M18-BlankBox/p/5881700.html
- [Think] position与anchorPoint关系
1.简介: 最近在学习动画,所以接触到了CAlayer类. 其中的position与anchorPoint关系一感觉一头雾水,网上有篇文章 彻底理解position和anchorPoint关系 里面 ...
- ie6下面不支持!important的处理方法
例子: #box { color:red !important; color:blue; } 这个例子应该是大家经常见到的important的用法了,在IE6环境下,这行字是蓝色 ...