1. 程式人生 > 實用技巧 >字串 Manacher 計算最長迴文子串

字串 Manacher 計算最長迴文子串

計算最長迴文子串Manacher

馬拉車

複雜度:O(n)

計算最長迴文子串的暴力方法

i 從頭開始遍歷,每次都以 i 為中心向外擴充套件

弊端:不適用於偶數迴文,且複雜度為O(n^2^)

Manacher

Manacher演算法詳解 - BT-7274 - 部落格園 (cnblogs.com)

int Manacher(string s)
{
	if(s.length() == 0) return 0;
    int len = (int)(s.length()*2-1);
    char *cArry = new char[len];
    int *pArry = new int[len];
    //預處理:全都變成奇數迴文串
    for(int i = 0; i < len; i++)
        cArry[i] = i&1 ? s[(i-1)/2] : '#';
    //R:最右右邊界  C:與R對應的迴文中心 maxn:最大回文半徑,返回值為maxn-1
    //R實際上是最右邊界的右邊一位
    int R = -1;
    int C = -1;
    int maxn = 0;
    for(int i = 0; i < len; i++)
    {
        pArry[i] = i > R ? 1 : min(R-i, pArry[2*C-i]); //取得可能的最短的迴文半徑 *R是最右邊界的右邊一位
        while(i+pArry[i] < len && i-pArry[i] > -1)   //暴力計算
        {
            if(cArry[i+pArry[i]] == cArry[i-pArry[i]]) pArry[i]++;
            else break;
        }
        //更新
        if(i+pArry[i] > R)
        {
            R = i+pArry[i];
            C = i;
		}
        maxn = maxn(pArry[i], maxn);
    }
    //清空動態陣列
    delete[] cArry;
   	delete[] pArry;
    
    return maxn-1;
}

練習題

HDU 3068