最长回文子串长度

来源:互联网 发布:网络用词鸡汤什么意思 编辑:程序博客网 时间:2024/05/16 12:06
/*************************************************************************  * File Name: Solution.cpp  * Description:   * Author: Yuji CAO  * Mail: caoyuji@sogou-inc.com  * Created_Time: 2015-07-29 08时00分17秒  * Last modified: 2015-07-29 08时00分17秒 ************************************************************************/#include<iostream>#include<stdio.h>#include<vector>#include<string>#include<map>#include<set>#include<string.h>using namespace std;void preProc(vector<char>& dat){    vector<char> datRet;    datRet.push_back('#');    for(vector<char>::iterator it=dat.begin();it!=dat.end();++it){        datRet.push_back(*it);        datRet.push_back('#');    }    dat=datRet;}void postProc(vector<char>& dat){    vector<char> retDat;    for(vector<char>::iterator it=dat.begin();it!=dat.end();++it){        if(*it!='#'){            retDat.push_back(*it);        }    }    dat=retDat;}int proc(vector<char>& dat){    vector<int> p;    p.resize(dat.size());    int maxR=0;    int maxP=0;    for(int i=0;i<dat.size();++i){        if(i<maxR){            int leftI=2*maxP-i;            if(((2*leftI-p[leftI])>(2*maxP-maxR))&&(2*maxP-maxR>0)){                p[i]=p[leftI]-leftI+i;            }else{                p[i]=maxR;                int& curR=p[i];                while(2*i-curR>=0&&curR<dat.size()&&dat[curR]==dat[2*i-curR]){                    curR++;                }                //if(dat[curR]!=dat[2*i-curR])                    curR-=1;                if(maxR<p[i]){                    maxR=p[i];                    maxP=i;                }            }        }else{            p[i]=i;            int& curR=p[i];            while(2*i-curR>=0&&curR<dat.size()&&dat[curR]==dat[2*i-curR]){                curR++;            }            //if(dat[curR]!=dat[2*i-curR])                curR-=1;            if(maxR<p[i]){                maxR=p[i];                maxP=i;            }        }    }    int ret=p[0]-0;    for(int i=0;i<p.size();++i){        printf("%3d",p[i]);        if(p[i]-i>ret){            ret=p[i]-i;        }    }    printf("\n");    return ret;}int getLongestPalindrome(vector<char>& dat){    preProc(dat);    for(int i=0;i<dat.size();++i){        printf("%3d",i);    }    printf("\n");    for(auto ele:dat){        printf("%3c",ele);    }    printf("\n");    int ret=proc(dat);    postProc(dat);    return ret;}int main(){    char a[]="abcabcabdbac";    vector<char> dat(a,a+strlen(a));    int ret=getLongestPalindrome(dat);    cout<<ret<<endl;    return 0;}

分析

这个问题的关键点有两点:

  1. 通过插入特殊字符使得偶数长度的回文转换为奇数长度的回文处理:
    A B C A D A C D
    #A#B#C#A#D#A#C#D#
  2. 充分利用回文的对称性, 在扫描的过程中当前位置很可能在一个已知的对称结构中,这时需要充分利用对称结构,来计算回文.
0 0
原创粉丝点击