首页 > 其他分享 >Manacher

Manacher

时间:2023-04-04 15:26:24浏览次数:25  
标签:int Manacher mid ++ mr 字符串 回文

算法简介

Manacher 算法用于求解一串字符串中的最长回文子串的长度。

如:abab 的最长回文子串的长度为3。

时间复杂度

$ O(n) $

实现原理

1.构造

回文串有两种情况:

情况1:abba,其对称轴在两字符中间
情况2:abcba,其对称轴在中间字符上

由于 Manacher 算法只能处理第二种情况,所以要对给定字符串进行重新构造,构造方法如下:

例:对字符串 abbcac 进行构造

1.首先在字符串首段和末端添加开始符和结束符,一般用'$'和'^'表示。
2.对于每个字符,保证其左右两侧分别有一个'#'。

那么原字符串就变为 $#a#b#b#c#a#c#^,其任意回文子串都满足情况2

2. 算法思想

设数组 p[i]:以字符 a[i] 为中心的最大的回文串的半径长度。

处理步骤为从前向后枚举,过程中不断维护右边界最靠右的回文串。

其中 mid 为回文串对称轴位置,maxright(后简称为 mr )为最右边界。

对于遍历到的某个 a[i] 可以分为三种情况

① i 在内部且对称点回文串在内部


j 为以 mid 为对称轴的 i 的对称点,由于该区间内的字符串都是以 mid 为中心对称的,所以红色标注的区域也是对称的。

那么此时有 p[i] = p[j]。

② i 在内部且对称点回文串在外部

这里可得 i 的右侧边界一定等于 mr。

因为若超出的话,i 的红色区域右侧画斜杠部分与左侧部分对称,则与 j 的斜杠部分相同,则白色区域部分并不是以 mid 为中心的,边界最靠右的回文子串,所以 p[i] 最大只能到 mr 。

③ i 在外部

在外部则重新开始计算,令 p[i] = 1,然后不断对比求出 p[i]。

算法代码

const int N = 2e7+10;

int p[N];
char a[N],b[N];

// n 为题目给出的原字符串
int manacher(int n) {
    int k = 0;
    b[k ++ ] = '$',b[k ++ ] = '#';
    
    for (int i = 0 ; i < n ; i ++ ) b[k ++ ] = a[i], b[k ++ ] = '#';
    
    b[k ++ ] = '^';
    
    int mid,mr = 0;
    for (int i = 1 ; i < k ; i ++ ) {
        if(i < mr) p[i] = min(p[2 * mid - i] , mr - i);
        else p[i] = 1;
        
        while(b[i + p[i]] == b[i - p[i]]) p[i] ++ ;
        
        if(i + p[i] > mr) {
            mr = i + p[i];
            mid = i;
        }
    }
    
    int ans = 0;
    for (int i = 0 ; i < k ; i ++ ) ans = max(ans,p[i]);
    
    return ans - 1;
}

参考

[1] Acwing算法进阶课

标签:int,Manacher,mid,++,mr,字符串,回文
From: https://www.cnblogs.com/Crystar/p/17285640.html

相关文章

  • 算法学习笔记(13): Manacher算法
    Manacher算法形象的被译为马拉车算法这个算法用于处理简单的回文字符串的问题。可以在\(O(n)\)的复杂度内处理出每一个位置为中心的回文串的最长长度。为了避免出现......
  • manacher算法
    manacher算法斯♥哈♥学长的博客https://www.cnblogs.com/luckyblock/p/17044694.html#5140558为什么老师叫他马拉车算法/yiw简介我们都知道,求最长回文子串可以枚举每......
  • Manacher算法
    文章默认给定字符串中只会出现小写英文字母介绍通过已经学习了的字符串哈希,我们可以用\(O(n\logn)\)的时间复杂度求解一个串中的最长回文子串了,那么我们思考一下是......
  • 「笔记」manacher 算法
    目录写在前面简介算法流程复杂度证明写在最后写在前面才发现好久没写知识笔记了……神兵小将真好看,感觉好像年轻了十岁,有一种莫名的沉浸式的体验。还记得当年特别喜欢......
  • Manacher(马拉车)
    Manacher算法:最长回文串(以每个点为中心的回文串长度)直接上代码MY_Code://22.10.8Manacher顶级理解#include<bits/stdc++.h>usingnamespacestd;constintN=4e7;......
  • Manacher
    通过在字符串之间的每个空位内插入字符,是的奇数和偶数成为一样得情况,从而能够统一处理。用len[]记录每个点能够扩展出的最长半径,mx记录扩展到的最远右端点,id记录mx为右端......
  • 【模板】最长回文串长度 manacher
    \(pa_i\)表示以\(i\)为中心的(原串的)回文串长度#include<cstdio>#include<cstring>#include<algorithm>usingnamespacestd;typedeflonglongLL;intn,m,pa[......
  • 关于 manacher 的一个小细节
    在该算法中,我们需要用到一个数组hw[i],代表i的最大回文半径。而且这个半径不包括i本身(若串为ccc则hw为1)。这时最终答案为最大的hw减一。为什么要减一呢?最终......
  • manacher
    manacher\(manacher\),一个可以做到\(O(n)\)求解一个字符串中的所有回文子串。我们有一种\(O(n^2)\)的算法来求回文子串,枚举回文中心一点一点比较。基于\(O(n^2)\)......
  • HDU 3068 最长回文——————Manacher
    最长回文TimeLimit:4000/2000MS(Java/Others)MemoryLimit:32768/32768K(Java/Others)TotalSubmission(s):30806AcceptedSubmission(s):11310ProblemDescrip......