manacher算法
manacher,是一种线性时间复杂度求解回文字符串的算法。而且很短。
首先我们观察回文串,发现有长度为奇数的(以某个字符为对称中心)和长度为偶数的(以两个字符间的空位为对称中心)。为了方便我们把它们转化成一样的,我们在字符之间插入一个占位符#,这样所有回文串就变成了奇数长度。
然后观察转移的方式。我们根据回文串的对称性质,可以用对称中心左边已经处理过的字符的回文半径
(我现在才知道oiwiki的这个看起来像图的东西是个
观察可以得到,左边的
最后,为了尽可能转移更多的字符,我们需要找到右端点在最右边的一个回文串。这个保存一个指针扫就可以。
上个代码。
int main(){
scanf("%s",ch+1);len=strlen(ch+1)*2+1;//一定要+1保证头尾都是#
int r=0,mid=0;s[0]='~';//s[0]插入不同字符保证数组不越界
for(int i=1;i<=len;i++)s[i]=(i&1)?'#':ch[i>>1];//在字符中插入占位符
for(int i=1;i<=len;i++){
if(i<=r)f[i]=min(f[2*mid-i],r-i+1);//更新答案
while(s[i+f[i]]==s[i-f[i]])f[i]++;//暴力扩展
if(i+f[i]>r)r=i+f[i]-1,mid=i;//更新指针
ans=max(ans,f[i]);
}
printf("%d",ans-1);/*回文串真实长度
这个可以分类讨论一下 如果真实长度是奇数那么占位符一定比字符多1
而(字符数+占位符数)=2*回文半径-1
把+1和*2扔到左边 因为是奇数然后+1 /2答案就大了1 所以要-1
然后考虑偶数的情况 占位符仍然比字符多1 可以按类似的方法计算*/
}
这个算法的时间复杂度为什么是
快踩
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效