manacher算法处理最长的回文子串(二)

来源:互联网 发布:淘宝客户管理 编辑:程序博客网 时间:2024/06/07 04:57

      在上篇《manacher算法处理最长的回文子串(一)》解释了manacher算法的原理,接着给该算法,该程序在leetcode的最长回文子串中通过。首先manacher算法维护3个变量。一个名为radius[i]的数组,表示以i为中心轴承的回文子串的半径,如abcdcba中,字符d的下标为4,则他的radius[4]=3,下标的为0的a的半径为radius[0]=0,即中心轴不考虑其中。一个idx表示上一次以idx为中心轴的回文。如果当以i为中心的回文在以idx为中心的回文内。则idx不更新,否则处理完radius[i]后,需要把idx更新为i。最后一个rad维护idx能够包含最大的范围的下一个字符下标,事实上当i+radius[i]到到达rad时就需要更新idx。

代码:

复制代码
 1 class Solution { 2 public: 3     string longestPalindrome(string s) { 4         int n=s.size(); 5         string str(2*n+1,'0'); 6         bool flag=1; 7         int j=0; 8         int maxIdx=0; 9         for(int i=0;i<2*n+1;i++){10            if(flag){11                str[i]='#';12                flag=false;13            }else{14                str[i]=s[j++];15                flag=true;16            }17         }18         vector<int> radius(2*n+1,0);19         int idx=0;20         int rad=1;21         for(int i=1;i<2*n+1;i++){22             if(i>=rad){23                 forceExtend(str,radius,idx,rad,i);24                 maxIdx=(radius[i]>radius[maxIdx]?i:maxIdx);25             }else if(i<rad){26                 int j=2*idx-i;27                 int idx_radius=idx-radius[idx];28                 int j_radius=j-radius[j];29                 if(j_radius>idx_radius){30                     radius[i]=radius[j];31                 }32                 else if(j_radius<idx_radius){33                     radius[i]=idx+radius[idx]-i;34                 }else{35                     radius[i]=idx+radius[idx]-i;36                     int count=1;37                     while((i+radius[i]+count)<=str.size()&&(i-radius[i]-count)>=0&&str[i+radius[i]+count]==str[i-radius[i]-count])38                         count++;39                     radius[i]+=(count-1);40                     if(i+radius[i]>=rad){41                         idx=i;42                         rad=i+count;43                     }44                 }45                 maxIdx=(radius[i]>radius[maxIdx]?i:maxIdx);46             }47             48         }49         string ret=getMaxSubString(str,maxIdx,radius[maxIdx]);50         return ret;51     }52     void forceExtend(const string& str, vector<int>& radius,int &idx,int &rad,const int k){53         int count=1;54         while((k-count)>=0&&(k+count)<str.size()&&str[k-count]==str[k+count]){55             count++;56         }57         radius[k]=count-1;58         if(k+radius[k]>=rad){59             idx=k;60             rad=k+count;61         }62     }63     string getMaxSubString(const string &str,const int k,const int r){64         string ret(r,'0');65         int j=0;66         for(int i=k-r+1;i<=k+r;i+=2){67             ret[j++]=str[i];68         }69         return ret;70     }71     72 };
复制代码

 

原创粉丝点击