Manacher算法——最长回文子串(O(n))

 1 public static int Manacher(String A,int n){
 2         char AA[]=A.toCharArray();
 3         char BB[]=new char[2*n+3];
 4         int k=0;
 5          for(int i=1;i<=2*n+1;i=i+2){
 6              BB[i]=‘#‘;
 7              if(i+1<=2*n+1)BB[i+1]=AA[k++];
 8          }
 9          BB[0]=‘$‘;//防止数组越界
10          BB[2*n+2]=‘&‘;//防止数组越界
11          int len[]=new int[2*n+3];
12          int po=0;//最长回文子串的中心
13          int board=0;//最长回文子串的右边界
14          int sum=0;//最长回文子串长度
15          for(int i=1;i<=2*n+1;i++){
16              if(i<=board)len[i]=len[2*po-i]<(board-i)?len[2*po-i]:board-i;
17              else len[i]=1;
18         while(BB[i+len[i]]==BB[i-len[i]])
19             len[i]++;
20         if(i+len[i]>board){
21             board=i+len[i];
22             po=i;
23         }
24         sum=sum>len[i]?sum:len[i];
25     }
26          return sum>2?sum-1:0;
27 }

时间: 2024-10-06 10:15:58

Manacher算法——最长回文子串(O(n))的相关文章

Manacher算法----最长回文子串

题目描述 给定一个字符串,求它的最长回文子串的长度. 分析与解法 最容易想到的办法是枚举所有的子串,分别判断其是否为回文.这个思路初看起来是正确的,但却做了很多无用功,如果一个长的子串包含另一个短一些的子串,那么对子串的回文判断其实是不需要的.同时,奇数和偶数长度还要分别考虑. Manacher算法可以解决上述问题,并在O(n)时间复杂度内求出结果.下面我们来看一下Manacher算法. 首先,为了处理奇偶的问题,在每个字符的两边都插入一个特殊的符号,这样所有的奇数或偶数长度都转换为奇数长度.比

manacher求最长回文子串算法

原文:http://www.felix021.com/blog/read.php?2040 首先用一个非常巧妙的方式,将所有可能的奇数/偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一个特殊的符号.比如 abba 变成 #a#b#b#a#, aba变成 #a#b#a#. 为了进一步减少编码的复杂度,可以在字符串的开始加入另一个特殊字符,这样就不用特殊处理越界问题,比如 @#a#b#a#(注意,下面的代码是用C语言写 就,由于C语言规范还要求字符串末尾有一个'\0'所以正好OK,但其

Manacher算法 最长回文串

Manacher算法O(n) 因为对于偶回文,是需要从虚轴扩充,ab,ba,所以如下: 先把原字符串处理,都加上一个标记符,比如#(特殊字符任何都可以,对于计算结果不会有影响) 1221-->#1#2#2#1# 121-->#1#2#1# 按照处理后的字符串求它的最长回文串长度m,所以原始字符串最长子回文串的长度是m/2 变量: 1:PArra[] 存放回文半径:某个位置能扩充的回文半径的长度,例如 #1#2#2#1#,2位置PArra[3] = 4 2:int PR 能够扫到的最右的回文的位

manacher hihoCoder1032 最长回文子串

居然能够做到O(n)的复杂度求最长回文.,也是给跪了. 以下这个人把manacher讲的很好,,能够看看 http://blog.csdn.net/xingyeyongheng/article/details/9310555 我就照着他的代码敲了一遍贴了个模板.. #include<map> #include<set> #include<cmath> #include<stack> #include<queue> #include<cstd

Manacher算法—最长回文串

若字符串长度为n,则算法的时间复杂度为o(n) 假设有一个字符串abaaba 先把该字符串变成$  #  a  #  b  #  a  #  a  #  b  #  a  # 第一个字符设为'$',防止计算的时候数组越界 再计算p数组,先给出p数组的答案 i为坐标,ma数组放改变后的字符串,p数组代表以该字符为中心,向右和向左延伸p[i]个,是回文串 i      0  1  2  3  4  5  6  7  8  9  10 11 12 13ma[]   $  #  a  #  b  # 

LeetCode 5 Longest Palindromic Substring manacher算法,最长回文子序列,string.substr(start,len) 难度:2

https://leetcode.com/problems/longest-palindromic-substring/ manacher算法相关:http://blog.csdn.net/ywhorizen/article/details/6629268 class Solution { public: string longestPalindrome(string s) { char ch[2001];int p[2001]; ch[2*s.size()] = 0; for(int i =

manacher求最长回文子串算法模板

#include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> #include <string> #include <math.h> #include <stdlib.h> using namespace std; int p[maxn]; char s[maxn]; void manacher(char *s){//时间复杂度O(

求最长回文子串,O(n)复杂度

最长回文子串问题-Manacher算法 最长回文串问题是一个经典的算法题. 0. 问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 如果一个字符串正着读和反着读是一样的,那它就是回文串.下面是一些回文串的实例: 12321 a aba abba aaaa tattarrattat(牛津英语词典中最长的回文单词) 1. Brute-force解法 对于最长回文子串问题,最简单粗暴的办法是:找到字符串的所有子串,遍历每一个子串以验证它们是否为回文串.一个子串由子串的起点和终点确定

[hiho 01]最长回文子串、Manacher算法

题目描述 - 基础方法:枚举子串,判断是否为回文串. - 改进:枚举中间位置,向两侧拓展. - 再改进:利用以前的信息,使得不用每个新位置都从长度1开始拓展. - 优化:将字符串预处理为奇数长度以避免考虑条件分支. - 再优化:开头加入特殊字符避免考虑边界. Manacher 算法: id 是中心点,mx 是其边界.P[i] 表示以 i 为中心的最长回文子串的折半长度. 只要 i < mx, 以 i 为中心的回文子串就可以不必从长度1开始找,而从min{P[j], mx - i}开始(其中j为i