最长回文子串---Manacher算法

本文介绍了一个解决LeetCode上最长回文子串问题的算法实现,通过预处理字符串并使用中心扩展法来寻找最长回文子串。该方法首先将原始字符串进行特殊字符插入处理,然后利用动态规划思想记录已知的最大回文半径。

其实我根本不知道我写的对不对,因为我这个在Leetcode上跑的时间好像比较慢....

学习资料转自此处

下面是自己写的代码(丑到死)

string longestPalindrome(string s){
    int rad[2005];
    for(int i = 0 ; i < 2005 ; i++) rad[i] = 0;
    string str;
    str.clear();
    str.push_back('#');
    for(int i = 0 ; i < s.size() ; i++){
        str.push_back(s.at(i));
        str.push_back('#');
    }
    rad[1] = 1;
    int MaxRight = 2;
    int pos = 1;
    for(int i = 2 ; i < str.size() ; i++){
        //cout << str.at(i) << endl;
        if(i >= MaxRight){
            int j = 1;
            int temp = str.size() - i - 1;
            for( ; j <= min(temp , i) ; j++){
                if(str.at(i+j) != str.at(i-j)){
                    j--;
                    break;
                }
            }
            j = min(min(temp , i) , j);     //这里最后J的值有点问题。如果加到边界会多一。
            MaxRight = i + j;
            rad[i] = j;
            pos = i;
            if(MaxRight == str.size() - 1) break;
            //cout << "randge = " << min(temp , i) << endl;
            //cout << "j = " << j << endl;
        }
        else{
            int ki = pos - (i - pos);
            int LM = pos - (MaxRight - pos);
            int j = min(ki - LM , rad[ki]) + 1;
            int temp = str.size() - i - 1;
            for( ; j < min(temp , i) ; j++){
                if(str.at(i+j) != str.at(i-j)){
                    j--;
                    break;
                }
            }
            if(i+j > MaxRight){
                MaxRight = i+j;
                pos = i;
            }
            rad[i] = j;
            if(MaxRight == str.size() - 1) break;
        }
    }
    int max_rad = -1;
    for(int i = 0 ; i < str.size() ; i++){
        if(rad[i] > max_rad){
            max_rad = rad[i];
            pos = i;
        }
    }
//debug:
    /*cout << "rad : \n";
    for(int i = 0 ; i < str.size() ; i++){
        cout << str.at(i) << " ";
    }
    cout << endl;
    for(int i = 0 ; i < str.size() ; i++){
        cout << rad[i] << " ";
    }
    cout << endl;*/

//debug

    if(str.at(pos) != '#') pos = (pos + 1) / 2 - 1 - (max_rad - 1) / 2;
    else pos =  pos / 2 - 1 - (max_rad - 2) / 2;
    str = s.substr(pos , max_rad);
    return str;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值