算法学习|刷题记录|马拉车算法(Manacher)—解决最长回文子字符串问题

解决最长回文子字符串问题——参考例题:力扣 .5

算法思路:首先定义变量:(创建数组rd)记录每一个位置上的最长回文子字符串的长度,设定当前最大回文子字符串的中心位置pos,对应的最右边界mx。

当到达位置 i 处,分两大类讨论:

1、当 i >mx,那么直接外扩查找回文子字符串

2、i 位置在目前的最右边界内,即 i < mx, 找到对位置 i' (pos-(i-pos)),根据之前记录的rd数组,判断i对应的回文子字符串多长。具体判断分3种情况:

1)i ' 对应的回文字符串在目前最大回文子字符串内部,那么rd[i]=rd[i'];

2) i ' 对应的回文字符串有一部分在目前最大回文子字符串外部,那么rdmx-i;

3)第三种,刚好与目前最大会文字字符串重合,那么就外扩查找。

其中1),2)可以合并在一起。

代码如下:

class Solution {
public:
    string longestPalindrome(string s) {
     int n=s.size();
     string res="%#"; //避免越界
     for(int i=0;i<n;i++)
     {
       res+=s[i];
       res+='#';  //将字符串长度变成偶数
     }
     vector<int>rd(res.size(),0);
     int pos=0,mx=0;//当前最大回文子字符串的中心位置,最右边界
     int start=0,maxlen=0;//最大子字符串的起点位置,最大长度
     for(int i=1;i<res.size();i++){
         rd[i]=i<mx?min(rd[2*pos-i],mx-i):1;  //当i的位置在当前最大回文串右边界左边的时候,两种情况合并写在一起
         while(i+rd[i]<res.size()&&i-rd[i]>0&&res[i+rd[i]]==res[i-rd[i]]) //向外扩展
         {
             rd[i]++;
             }
        if(i+rd[i]>mx){
                 pos=i;
                 mx=rd[i]+i;//更新最大回文半径,还有对应的中心位置
             }
        if(rd[i]-1>maxlen){
                 start=(i-rd[i])/2;
                 maxlen=rd[i]-1; //计算最大回文子串的起始位置和半径长度
             }  
     }
     return s.substr(start,maxlen);
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值