最长回文子串长度

/*************************************************************************
  * 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. 充分利用回文的对称性, 在扫描的过程中当前位置很可能在一个已知的对称结构中,这时需要充分利用对称结构,来计算回文.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值