manacher演算法:
定義陣列p[i]表示以i為中心的(包含i這個字元)回文串半徑長
將字串s從前掃到後for(int i=0;i由於s是從前掃到後的,所以需要計算p[i]時一定已經計算好了p[1]....p[i-1]
假設現在掃瞄到了i+k這個位置,現在需要計算p[i+k]
定義maxlen是i+k位置前所有回文串中能延伸到的最右端的位置,即maxlen=p[i]+i;//p[i]+i表示最大的
分兩種情況:
1.i+k這個位置不在前面的任何回文串中,即i+k>maxlen,則初始化p[i+k]=1;//本身是回文串
然後p[i+k]左右延伸,即while(s[i+k+p[i+k]] == s[i+k-p[i+k]])++p[i+k]
2.i+k這個位置被前面以位置i為中心的回文串包含,即maxlen>i+k
這樣的話p[i+k]就不是從1開始
由於回文串的性質,可知i+k這個位置關於i與i-k對稱,
所以p[i+k]分為以下3種情況得出
//黑色是i的回文串範圍,藍色是i-k的回文串範圍,
manacher演算法例題hdu-3068
#include#include#include#include#include#include#include#includeusing namespace std;
#define maxn 110010
char s[maxn*2];
int p[maxn*2];
int manacher(char s)
//首尾s[0]和s[2*len+2]要插入不同的字元
s[0]='@'; //s[0]='@',s[len+len+2]='\0',防止在while時p[i]越界
for(int i=2;i<2*len+1;i++)
return maxlen - 1;
}int main()
return 0;
}
求最長回文串 Manacher演算法
o n 效率的字串求最長回文串,感覺這個blog上寫的很詳細 有幾個要點 1 先要將字串擴充套件成2 l 1長度的,在每兩個字元之間要加上乙個用不到的字元,比如 方便處理偶數回文串。2 在擴充套件後的字串兩端要加一些特殊字元,防越界。3 ra i 陣列表示以i為中點的最長回文串,mx表示以j 1 j...
manacher演算法 O n 求最長回文子串
樸素的做法是求出以每個字元為中心的回文串長度,複雜度為 而manacher演算法可以在o n 時間內求解,奇數長度和偶數長度可以統一處理。根據回文串的對稱性,避免了大量不必要的比較。處理技巧 相鄰的字元之間插入乙個分隔符,串的首尾也要加,以 為例,則長度為n的字串經過處理之後變成2n 1奇數長度的字...
求最長回文子串 Manacher 演算法
給定乙個字串,求出其最長回文子串。例如 1 s abcd 最長回文長度為 1 2 s ababa 最長回文長度為 5 3 s abccb 最長回文長度為 4,即 bccb。以上問題的傳統思路大概是,遍歷每乙個字元,以該字元為中點向兩邊查詢。其時間複雜度為 o n2 很不高效。1975 年,乙個叫 m...