馬拉車(Manacher)算法(求最大回文子串)

馬拉車(Manacher)算法是一種時間複雜度爲O(n)的求字符串中的最大回文子串的算法,
他很好的利用了迴文串是關於中間字符對稱的特點進行了剪枝操作,把時間複雜度優化到了O(n),並且它可以無差別處理奇偶字符串。

牆裂建議配合B站視頻食用,我愛死這破站了

UESTCACM 每週算法講堂 manacher算法1(原理和思想)
UESTCACM 每週算法講堂 manacher算法2(代碼與實現)

我比較推薦看下面那個2,對着題邊敲邊講,還是挺容易理解,如果看了這兩個視頻還是不理解的話,那就看看這個博客吧 —> Manacher Algorithm 馬拉車算法(感謝博主) <— 或者也可以先看這個博客再去看視頻。

然後我就直接附上板子了。

#include<bits/stdc++.h>
using namespace std;

const int maxn = 3e3;
char s[maxn],str[maxn];
int len1,len2,p[maxn];

void manacher()
{
    int id = 0,mx = 0;
    for(int i = 1; i< len2; i++)
    {
        if(mx > i) p[i] = min(p[2*id-i],mx-1);
        else p[i] = 1;
        for(; str[i+p[i]] == str[i-p[i]]; p[i]++);
        if(p[i] + i > mx)
        {
            mx = p[i]+i;
            id = i;
        }
    }
}

void init()
{
    str[0] = '$';
    str[1] = '#';
    for(int i = 0; i < len1; i++)
    {
        str[i*2+2] = s[i];
        str[i*2+3] = '#';
    }
    len2 = len1*2+2;
    str[len2] = '*';
}

int main()
{
    int n;
    cin >> n;
    while(n--)
    {
        cin >> s;
        len1 = strlen(s);
        init();
        manacher();
        int ans = 0;
        for(int i = 0; i < len2; i++)
        {
            ans = max(ans,p[i]);
        }
        cout << ans-1 << endl;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章