AlenaNuna

导航

Manacher算法讲解||HJ32 密码截取

HJ32 密码截取

题目:https://www.nowcoder.com/practice/3cd4621963e8454594f00199f4536bb1?tpId=37&tqId=21255&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3FtpId%3D37&difficulty=undefined&judgeStatus=undefined&tags=&title=

这个题目范围n才2500,随便什么暴力都能做(谢谢华为,你真善良)。但是我想复习一下Manacher,又想起自己没怎么写过算法讲解的帖子,(而且自己以前写的板子长得很丑陋),就干脆作为manacher模板题,详细讲解一下Manacher算法。

Manacher算法是一种高效的算法,用于在字符串中找到最长的回文子串。它的时间复杂度是O(n),非常适合处理长字符串。

Manacher算法的基本思想

1. 插入特殊字符:

为了处理奇数长度和偶数长度的回文子串,Manacher算法首先在原字符串的每个字符之间插入一个特殊字符(例如`#`),并在字符串开始和结尾也插入特殊字符。这样可以将所有回文子串统一处理为奇数长度。
- 例如,将字符串"abc"转换为"#a#b#c#"

但是我倾向于在字符串左右边界加上两个不同的特殊字符,比如将“abc”转换为“^#a#b#c#$”。这样代码的容错率较大,判断时也不用特判边界情况。

2. 使用辅助数组P:

算法使用一个辅助数组P,P[i]表示以字符T[i]为中心的最长回文子串的半径(不包括字符T[i]本身)。

3. 中心扩展法:

算法通过扩展回文子串的中心,动态更新辅助数组P,并利用已经计算出的回文子串信息来减少重复计算。

4. 维护一个最右回文边界:

算法在遍历过程中,维护一个最右回文边界R和其对应的中心C。如果i在R的范围内,算法利用对称性来减少计算。

具体细节写在代码注释里了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 // 预处理函数:在每个字符之间插入特殊字符
 4 string Preprocess(const string&s){
 5     string t;
 6     if(s.empty()){
 7         t="^$";// 如果输入字符串为空,返回特殊处理后的字符串
 8         return t;
 9     }
10     t="^"; // 插入字符串开头的特殊字符
11     int n=s.size();
12     for(int i=0;i<n;i++)
13         t=t+'#'+s[i];// 在每个字符前插入特殊字符#
14     t=t+"#$";// 插入字符串结尾的特殊字符
15     return t;// 返回预处理后的字符串
16 }
17 // Manacher算法:寻找最长回文子串
18 int Manacher(const string&t){
19     int n=t.size();
20     vector<int>p(n,0);// 辅助数组p,存储回文子串的半径
21     int R=0,C=0;// R为最右回文边界,C为回文中心
22     for(int i=1;i<n;i++){
23         int mirr=C*2-i;//mirror
24         if(R>i) p[i]=min(R-i,p[mirr]);
25         while(t[i+p[i]+1]==t[i-p[i]-1]) p[i]++;
26         if(i+p[i]>R){
27             R=i+p[i];// 更新最右回文边界R和回文中心C
28             C=i;
29         }
30     }
31     int ans=0;
32     // 找到p中的最大值,即最长回文子串的长度
33     for(int i=1;i<n;i++) ans=max(ans,p[i]);
34     return ans;// 返回最长回文子串的长度
35 }
36 int main(){
37     string s,t;
38     cin>>s;// 读取输入字符串
39     t=Preprocess(s);// 调用预处理函数
40     cout<<Manacher(t);// 调用Manacher算法函数并输出结果
41     return 0;
42 }

by:AlenaNuna

posted on 2024-09-09 01:13  AlenaNuna  阅读(7)  评论(0编辑  收藏  举报