華爲OJ-最長迴文子串-Manacher算法

題目描述

給定一個字符串str,返回str中最長迴文子串的長度。html

示例

輸入ios

ABBAc++

輸出算法

4spa

求解方法

採用經典的Manacher算法,時間複雜度爲\(log{N}\)code

代碼及註釋以下:htm

#include <iostream>
#include <vector>
using namespace std;

int manacher(const string & str){
    if(str.size() == 0) return 0;
    string mana_str;
    // 插入間隔符#
    for(int i = 0; i < str.size(); ++i){
        mana_str +='#';
        mana_str += str[i];
    }
    mana_str += '#';

    int index = -1;     //記錄pR所對應的迴文子串對稱軸的位置
    int pR = -1;        //當前訪問到的全部迴文子串中,所能觸及到的最大位置的下一個
    int max_len = 0;    //記錄最長迴文子串長度
    vector<int> pArr(mana_str.size()); //記錄以i爲對稱軸的最長迴文子串的半徑
    for(int i = 0; i < mana_str.size(); ++i){
        //分兩種狀況,i在pR的左側或右側
        pArr[i] = pR > i? min(pArr[2 * index - i], pR - i) : 1;

        while(i + pArr[i] < mana_str.size() && i - pArr[i] > -1){
            //以i爲中心,在上步的基礎上擴展,直至到達邊界或者字符不相等
            if( mana_str[i + pArr[i]] == mana_str[i - pArr[i]])
                pArr[i] ++;
            else
                break;
        }
        // 更新pR和index
        if(i + pArr[i] > pR){
            pR = i + pArr[i];
            index  = i;
        }
        max_len = max(max_len, pArr[i]);
    }
    //對以i爲中心的迴文子串,其在原串中的長度爲pArr[i] - 1
    return max_len - 1;
}
int main() {
    ios::sync_with_stdio(false);
    string password;
    while(cin >> password){
        cout << manacher(password)<<endl;
    }

    return 0;
}
相關文章
相關標籤/搜索