最長回文子串

2021-07-24 11:49:52 字數 1713 閱讀 5049

/*hiho 1032*/

manacher演算法理解

首先,manacher演算法提供了一種巧妙地辦法,將長度為奇數的回文串和長度為偶數的回文串一起考慮,具體做法是,在原字串的每個相鄰兩個字元中間插入乙個分隔符,同時在首尾也要新增乙個分隔符,分隔符的要求是不在原串中出現,一般情況下可以用#號。下面舉乙個例子:

manacher演算法用乙個輔助陣列len[i]表示以字元t[i]為中心的最長回文字串的最右字元到t[i]的長度,比如以t[i]為中心的最長回文字串是t[l,r],那麼len[i]=r-i+1。

對於上面的例子,可以得出len[i]陣列為:

len 陣列有乙個性質,那就是len[i]-1就是該回文子串在原字串s中的長度,至於證明,首先在轉換得到的字串t中,所有的回文字串的長度都為奇數,那 麼對於以t[i]為中心的最長回文字串,其長度就為2*len[i]-1,經過觀察可知,t中所有的回文子串,其中分隔符的數量一定比其他字元的數量多 1,也就是有len[i]個分隔符,剩下len[i]-1個字元來自原字串,所以該回文串在原字串中的長度就為len[i]-1。

首先從左往右依次計算len[i],當計算len[i]時,len[j](0<=j

第一種情況:i<=p

那麼找到i相對於po的對稱位置,設為j,那麼如果len[j]

那 麼說明以j為中心的回文串一定在以po為中心的回文串的內部,且j和i關於位置po對稱,由回文串的定義可知,乙個回文串反過來還是乙個回文串,所以以i 為中心的回文串的長度至少和以j為中心的回文串一樣,即len[i]>=len[j]。因為len[j]

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

第二種情況: i>p

如果i比p還要大,說明對於中點為i的回文串還一點都沒有匹配,這個時候,就只能老老實實地乙個乙個匹配了,匹配完成後要更新p的位置和對應的po以及len[i]。

直接套用模板

#include

#include

#include

using namespace std;

char str1[1000005];

char str[1000005*2];

int p[1000005*2];

int manacher()

if(p[i]>max)

max=p[i];

}return max-1;//p陣列減1就是每個字串的回文串的長度

}int main()

str[j]='\0';

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

}return 0;

}

最長回文子串 最長回文子串行

1.最長回文子串行 可以不連續 include include include include using namespace std 遞迴方法,求解最長回文子串行 intlps char str,int i,int j intmain include include include using n...

最長回文子串

描述 輸入乙個字串,求出其中最長的回文子串。子串的含義是 在原串連續出現的字串片段。回文的含義是 正著看和倒著看是相同的,如abba和abbebba。在判斷是要求忽略所有的標點和空格,且忽略大小寫,但輸出時按原樣輸出 首尾不要輸出多餘的字串 輸入字串長度大於等於1小於等於5000,且單獨佔一行 如果...

最長回文子串

輸入乙個字元,求出其中最長的回文子串。子串的含義是 在元串中連續出現的字串片段。回文的含義是 正看和倒看相同,如abba和yyxyy,在判斷時候應該忽略所有的空格和標點符號,且忽略大小寫,但輸出應該保持原樣,輸入的字元長度不超過5000,且佔據單獨一行,輸出最長的回文子串 如有多個,輸出,起始位置最...