Manacher演算法總結 HDOJ3068

2021-08-21 13:59:43 字數 2112 閱讀 4530

看到了兩篇講manacher演算法jian講得很詳細的bow博文,在此記錄一下:

manacher演算法(民間稱馬拉車演算法233)是用來找字串中的最長回文子串的,先來說一下什麼是回文串,像這樣「abcba」這樣乙個字串找到乙個中間位置,然後分別向他的左邊和右邊相等的距離位置的字元是相同的,那麼這個字串就稱為回文串,「abcba」這個字串的len為5是奇數,我們可以找到乙個中間字元,然後進行搜尋也可以找出來(當然時間複雜度是比較高的),但是當我們遇到乙個長度為偶數的字串時該怎麼找中間字元呢,像這樣「abccba」,下面我們引入manacher演算法,這是乙個可以將長度為奇數或偶數的字串一起考慮的神奇演算法

manacher演算法可以將長度為奇數和偶數的回文串一起考慮:在原字串的相鄰字串之間插入乙個分隔符,字串的首尾也要分別新增,注意分隔符必須是原字串中沒有出現過的

原字串sab

abc轉換後字串str#a

#b#a

#b#c

#一、len陣列的簡單介紹

manacher演算法中用到乙個非常重要的輔助陣列len[i]表示以str[i]為中心的最長回文子串的最右端到str[i]位置的長度,比如以str[i]為中心的最長回文串是str[l,r],那麼len[i]=r-i+1

轉換後的字串str#a

#b#a

#b#c

#len12

1414

1212

1 len[i]陣列有乙個性質,len[i]-1就等於該回文串在原串s中的長度

證明:在轉換後的字串str中,所有的回文串的長度都是奇數,那麼對於以str[i]為中心的最長回文串的長度為2*len[i]-1,其中又有len[i]個分隔符,所以在原字串中的長度就是len[i]-1,那麼剩下的工作就是求len陣列

二、len陣列的計算

從左往右開始計算,假設0<=j<=i,那麼在計算len[i]時,len[j]已經計算過了,設mx為之前計算過的最長回文串的右端點,id為取得這個端點值得位置(那麼len[id]=mx-id+1)

第一種情況:i<=mx.

找到i相對於id的對稱位置,設為j,再次分為兩種情況:

mx的對稱點為2*id-mx,i和j所包含的範圍是2*len[j]-1

那麼說明以j為中心的回文串一定在以id為中心的回文串內部,且i和j關於id對稱,由回文串的定義可知,乙個回文串反過來仍是回文串,所以以i為中心的回文串長度至少和以i為中心的回文串長度相等,即len[i]>=len[j].因為len[j]2、len[j]>=mx-i

由對稱性說明以i為中心的回文串可能延伸到mx之外,而大於mx的部分我們還沒有進行匹配,所以要從mx+1位置開始乙個乙個匹配直到失配,從而更新mx和對應的id以及len[i]

第二種情況,i>mx

如果i比mx還大,說明對於中點為i的回文串一點都沒匹配,這個時候只能乙個個匹配(滑稽),匹配完成後更新mx的位置和對應的id及len[i].

**實現:

#include#include#includeusing namespace std;

const int maxn=1e6+5;

char s[maxn*2],str[maxn*2];

int len[maxn*2],len;

void getstr()

}int main()

else p[i] = 1;

while(str[i - p[i]] == str[i + p[i]]) p[i] += 1;

if(i + p[i] > mx)

ans = max(ans, p[i] - 1);

}return ans;

}int main()

str[0] = '$';

printf("%d\n", manacher());}}

好了,到此希望大家能夠對於manacher演算法有了更深的了解。

Manacher演算法總結

所謂回文串,簡單來說就是正著讀和反著讀都是一樣的字串,比如abba,noon等等,乙個字串的最長回文子串即為這個字串的子串中,是回文串的最長的那個。下面介紹manacher演算法的原理與步驟。首先,manacher演算法提供了一種巧妙地辦法,將長度為奇數的回文串和長度為偶數的回文串一起考慮,具體做法...

Manacher演算法總結

演算法總結第三彈 manacher演算法,前面講了兩個字串相演算法 kmp和拓展kmp,這次來還是來總結乙個字串演算法,manacher演算法,我習慣叫他 馬拉車 演算法。相對於前面介紹的兩個 演算法,manacher 演算法的應用範圍要狹窄得多,但是它的思想和拓展kmp 演算法有很多共通支出,所以...

manacher演算法總結

原文 1 len陣列簡介與性質 manacher演算法用乙個輔助陣列len i 表示以字元t i 為中心的最長回文字串的最右字元到t i 的長度,比如以t i 為中心的最長回文字串是t l,r 那麼len i r i 1。對於上面的例子,可以得出len i 陣列為 2 len陣列的計算 首先從左往右...