最长回文子串 V2(Manacher算法)

题目描述

回文串是指aba、abba、cccbccc、aaaa这种左右对称的字符串。

输入一个字符串Str,输出Str里最长回文子串的长度。

输入格式

输入Str(Str的长度 <= 100000)

输出格式

输出最长回文子串的长度L。

样例

【样例输入】

复制代码
daabaac

【样例输出】

复制代码
5

一些想法

这道题用 Manacher 算法做会更高效且简单。

算法的优化方法主要是可以不用多次求新的回文子串长度,可以直接用已有答案求出范围内答案。

定义变量:int 类型的有原字符串长度、新字符串长度和回文子串半径长度数组。char 类型的有 原字符串和新字符串(都是数组)。

主函数:输入原字符串加一,获取原字符串长度加一(要加一是要将从下标 0 开始移到从下标 1 开始,方便添加"哨兵"),然后直接调用 Manacher 函数输出。

Manacher 自定义函数:新字符串长度等于原字符串长度 乘 2 加 1,乘二是因为每个数前面要加一个字符,加一是因为要在新字符串最后也加一个"哨兵"字符。然后添加哨兵字符,新字符串第 0 位 和最后一位(m+1)等于一个不同的字符,以防越界(避免后面判断越界,更简便),然后将新字符串第一位初始化为分隔字符。循环原字符串每一个字符,将新字符串中奇数下标的字符等于分隔符,偶数下标的字符等于对应的原字符串的字符。(这里是在构建新字符串)

将用于记录最右回文子串中心点和最右点的变量初始化。循环新字符串每一个字符,初始每个字符的回文半径长度等于 1(自己也是一个回文子串,长度为一)。如果当前数在最右回文子串范围内,说明可以有根据求当前回文半径。将当前回文半径取当前点的对称点的回文半径和最右点到当前点的距离的最小值(因为对称点有可能会超出当前最右回文子串的范围,无法保证超出部分回文,如果超出,直接用最右点到当前点的距离,将超出部分暂时抛开)。

扩展半径。如果在当前点在新字符串中超出的左部分和超出的右部分相等,说明超出部分也回文,可以扩展半径,将当前回文半径加一。

更新最右回文子串的中心点和最右点。如果新的回文子串的最右点比当前记录的最右点大,说明需要更新,更新两个点。(方便后面的数计算)

找完所有点(中心点)的回文半径后,找当中的最大值。循环整个新字符串,找到最大的回文半径减一(减一原因看上一篇或看下面)。返回最大值。

这里复习一遍 Manacher 算法的描述与证明:

AC代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,m,p[1000005];
char ch[1000005],st[1000005];
int manacher(){
	m=2*n+1;
	st[0]='+',st[m+1]='-',st[1]='#';
	for(int i=1;i<=n;i++){
		st[i<<1]=ch[i];
		st[i<<1|1]='#';
	}
	int maxid=0,id;
	for(int i=1;i<=m;i++){
		p[i]=1;
		if(i<maxid){
			p[i]=min(maxid-i,p[id*2-i]);
		}
		while(st[p[i]+i]==st[i-p[i]]){
			p[i]++;
		}
		if(p[i]+i>maxid){
			maxid=p[i]+i;
			id=i; 
		}
	}
	int maxn=0;
	for(int i=1;i<=m;i++){
		maxn=max(maxn,p[i]-1);
	}
	return maxn;
}
int main(){
	scanf("%s",ch+1);
	n=strlen(ch+1);
	cout<<manacher();
	return 0;
}
相关推荐
依然鸣5 分钟前
PTA团体程序设计天梯赛L2真题讲解L2-001-004
经验分享·学习·算法·深度优先·pat考试
SNAKEpc1213813 分钟前
OpenGL(十三)- Mip贴图
c语言·c++·图形渲染·贴图
杨航 AI2 小时前
** AI 面试算法 50 题清单**,不是单纯的 LeetCode 题号列表,而是按照“**考察概率 × 面试价值 × 你当前准备方向**”排序
算法·leetcode·面试
m0_720245018 小时前
1543.统计好三元组(简单)
开发语言·算法
To_OC9 小时前
LC 560 和为 K 的子数组:前缀和配哈希表,这对组合我是真的服了
javascript·算法·程序员
hans汉斯9 小时前
《软件工程与应用》期刊推荐&10月版面征稿中
图像处理·人工智能·深度学习·算法·音视频·软件工程
叠层归一研究院10 小时前
AGI 系统(八):符号范畴嵌入函子 — SymCat ↪ C_M107 严格化
c语言·开发语言·人工智能·算法·transformer·agi
其美杰布-富贵-李11 小时前
08 进阶评估指标与算法特定指标
人工智能·算法
.道阻且长.11 小时前
5.LeetCode算法习题讲解--双指针--有效三角形的个数
算法·leetcode·职场和发展
我是海飞11 小时前
杰理JL703N SSD1306 OLED(128x64) 点阵屏移植说明
单片机·算法·嵌入式·音频·杰理