Manacher 算法(极大回文串的O(n)求法)

本文介绍了一个高效的算法——Manacher算法,该算法可以在O(n)的时间复杂度内找到字符串中各个字母所在的最大长度的回文串。文章通过两个关键结论及两种实现模板详细解释了Manacher算法的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Manacher 算法是一个高效的算法,像KMP一样。

算法简介:算法的目的是在O(n)的时间复杂度内找到一个字符串中各个字母所在的最大长度的回文串。

此算法用到了一个Rad[]数组的定义,Rad[i]表示回文的半径,即最大的j满足str[i-j+1...i] = str[i+1...i+j]。

我们的工作就是把全部的Rad[]求出来。

有两个结论:

(1): 对于一个整数k,如果 (1<=k<=Rad[i] && Rad[i-k] < Rad[i]-k ) 那么, Rad[i+k] = min( Rad[i-k], Rad[i]-k ).

(2) :  对于一个整数k,如果 (1<=k<=Rad[i] && Rad[i-k] > Rad[i]-k ) 那么, Rad[i+k] = min( Rad[i-k], Rad[i]-k ).

==================================================================

模板1:

char str[M];//start from index 1
int rad[M];
void Manacher()
{
	int i,j,k;
	i=1;j = 0;
	while(i< =n)
	{
		while(str[i-j] == str[i+j+1] && i-j>0 && i+j+1 < = n)
			j++;
		rad[i] = j;
		k = 1;
		while(k<=rad[i] && rad[i-k] != rad[i]-k)
		{
			rad[i+k] = min(rad[i-k],rad[i]-k);
			k++;
		}
		i = i+k;
		j=max(j-k,0);
	}
//Rad[] has obtain the ans
}


模板2.

void pk()
{
int i;
int mx = 0;
int id;
for(i=1; i<n; i++)
{
if( mx > i )
p[i] = MIN( p[2*id-i], mx-i );
else
p[i] = 1;
for(; str[i+p[i]] == str[i-p[i]]; p[i]++)
;
if( p[i] + i > mx )
{
mx = p[i] + i;
id = i;
}
}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值