萌新の马拉车算法

马拉车

该算法解决一长串字符的最大长度回文字符串(当然他的用处不仅局限于此)
普通解法 时间复杂度o(n*n) 马拉车算法 o(n)。

原串S: abbbab
变化后的 新串 T
T =@ # a # b # a # a # b # a #
P = 0 0 1 0 3 0 1 6 1 0 3 0 1 0 //p数组
//为什么要变化S,成新串,后续解释
发现了点端倪了吧 怎么会有p数组的值也是怎么对称呢。
1 0 3 0 1 6 1 0 3 0 1 (以后补,睡觉了)
链接: link.
这位大牛的代码解释原理的很好
题解思路来自于此。
马拉车原理:
主要是因为回文有对称关系,
就好比我已经知道一个回文串以中心点左边的每个点回文串长度
(可能说起来比较拗口,其实就是下文中的p数组)

#include<iostream>
#include<cstring>
using namespace std;
#define maxn 100005
char s[maxn],news[2*maxn];
int p[2*maxn];
int len;
void bian(){   //长度变两倍
	news[0] = '@';
	news[1] = '#';
	for(int i=1;i<=len;i++)
	{   news[2*i] = s[i];
	    news[2*i+1] = '#';
	}
 	  //cout<<news<<endl;
 	  for(int i=1;i<=2*len+1;i++){
 	  	 cout<<news[i]<<" ";
	   }
	   cout<<endl;
	   return ;
}
void Pzu(){   //p数组
	int lens = 2*len +1;
	int id,mx = 0;  // mx = id + p[id] 懂的都懂
	// id 回文中点 mx 子串回文末端
	for(int i=1;i<=lens;i++){
		if(i<=mx)
		   p[i] = min(p[2*id-i],mx-i); 
		   
    //若是mx-i 说明回文p[2*id-i]已经超出mx的范围。
    // 在以id 为 中心 半径为p[id].
		else 
		   p[i]  =1 ;
		while(news[p[i]+i]==news[i-p[i]])  p[i]++;
	  if(i+p[i]>mx)
	      mx=i+p[i],id =i;
	}
	for(int i=1;i<=lens;i++)
	  cout<<p[i]<<" ";  //马拉车p数组,最大回文串长度pmax-1
	return ;
}
int main (){
	 scanf("%s",s+1);
	  len = strlen(s+1);//字符串长度
	 bian();
	 Pzu(); 
}
//样例:babcbabcbaccba
//最大回文数为 9  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

axtices

谢谢您的打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值