数据结构--Manacher算法(最长回文子串)

在字符串中求出其最长回文子串

可能是奇回文也可能是偶回文,要考虑全面

暴力解法:(因为存在奇回文和偶回文的问题,所以不好找,有一个技巧,就是想字符串中每个字符之间添加一个符号(任意符号,也可以是字符串中的符号),然后在每个位置向两端开始扩充)

答案就是最大值/2

Manacher算法: 字符串中每个字符串之间也要加上一个字符

回文直径:从某个位置开始向两边扩的最大长度

1. 回文半径数组:arr[],以每个位置为中心能扩出来的回文半径的长度

2. 最右回文右边界R:所有回文半径中,最靠右的位置

  开始位置为-1

3. 回文右边界的中心  当前回文右边界到达最右边时,是以哪个位置为中心进行扩充的

算法:

1.当前位置为 i   可能性1:i 不在回文右边界R内,则采用暴力扩充

       可能性2:i 在回文右边界R内,且 i 关于回文右边界中心的对称位置 i’ 的回文中心的半径  全部在L 和 R内部

            此时 i 位置的回文区域的半径和 i‘ 一样

        

       可能性3:

       可能性4:

原文地址:https://www.cnblogs.com/SkyeAngel/p/8983100.html

时间: 2024-10-09 17:53:32

数据结构--Manacher算法(最长回文子串)的相关文章

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

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

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

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解法 对于最长回文子串问题,最简单粗暴的办法是:找到字符串的所有子串,遍历每一个子串以验证它们是否为回文串.一个子串由子串的起点和终点确定