左神进阶班- manacher 找到字符串的最长回文子串的长度

 

#include<iostream>
#include<string>
#include<algorithm>
#include<limits>
using namespace std;
//在字符串之间插入字符,从而 奇偶回文串都能识别
char* manacherString(string str){
	int length = str.size();
	char* res = new char[2*length + 1];
	int index = 0;
	for(int i=0;i<2*length + 1; i++){
		res[i] = (i&1) == 0? '#' : str[index++];
	} 
	return res;
}
int maxLcpsLength(string str){
	if(str.size() == 0)
		return 0;
	char* charArr = manacherString(str);
	int* pArr = new int[str.size()];
	int C = -1;
	int R = -1;
	int MAX = INT_MIN;
	for(int i=0;i<2*str.size()+1;i++){
		//pArr 可以有一个直接填的值,根据1.2.3.4的情况,填完后,我在看看能不能往外扩展
		pArr[i] = R > i? min(pArr[2*C - i], R-i) : 1;
		while(i+pArr[i] < (2*str.size()+1) && i - pArr[i] > -1){
			//如果当前外扩的两个字符相等,则i位置的值+1, 再取判断 左右又外扩一位的两个字符是否相等
			if(charArr[i+pArr[i]] == charArr[i-pArr[i]]){
				pArr[i]++;
			}else{
				break;
			}
		}
		//更新 最大回文右边界 R, 和回文中心C 的位置
		if(i+pArr[i] > R){
			R = i+pArr[i];
			C = i;
		}
		//每次在pArr中填完值后,更新MAX
		MAX = max(MAX,pArr[i]);
	}
	return MAX-1;
}  

int main(){
	cout <<"max: "<< maxLcpsLength("abcba");
	return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值