算法 manacher求最长回文

 

算法原理

 

1.由于字符串在字符数为偶数或奇数时存在不同情况,我们在字符间插入字符串本身不存在的字符,例如:abcdefg中插入#,字符串变为#a#b#c#d#e#f#g#,变化后的字符串一定有奇数个字符。并且以p[n]表示以第n个字符为中心的回文串的半径,p[n]-1为最终第n个字符回文长度。

 

2.回文串的一个性质:假设存在一个足够长的回文串A,并且此回文以字符A[i]为中心,则根据对称的性质,以A[i-k]为中心的回文串长度 (此回文串的左右边界不超过回文串A的边界) 等于以A[i+k]为中心的回文串长度。

3.令m为以求的回文串的最右边界,i为以m为右边界的回文串的中心点。初始化m为1,i为1。

 

4.求p[n]:当n<m,且以n为中心的回文边界小于m:p[n]=p[2n-i]。

 

                当n<m,且以n为中心的回文边界大于m:先令p[n]=m-n,在通过暴力解法判断未知部分。

 

                当n>=m时:直接通过暴力求解。

核心代码:

int manacher(char* str,int n){
  int p[n];
  int maxl=0;
  int m=1,co=0; p[0]=1;
  int i;
  for(i=1;i<n;i++){
    if(i<m){
      p[i]=min(p[2co-i],m-i);
    }
    else
    p[i]=1;
    while(str[i+p[i]]==str[i-p[i]]){p[i]++;}//暴力解法
    if(i+p[i]>m){
      m=i+p[i];
      co=i;
    }
    maxl=max(maxl,p[i]-1);
  }
  return maxl;
}
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值