2017/11/21
manacher問題
找出字串str中最長的回文子串
1、在解決最長回文子串問題前,要解決奇回文和偶回文的問題。我們在判斷奇回文時,是根據乙個字串,然後同時向兩邊擴充套件;偶回文則是直接向兩邊擴充套件,中間沒有字串。如下:
12a21 奇回文
1221 偶回文
為了解決這個問題,將原始字串進行改進,在原始字串的開頭、結尾以及字元之間新增乙個字元,如「#」,作為乙個虛軸。然後使用新的字串。這樣做不會改變原有的回文結構,而且新字串中所有的回文變為奇回文。
eg:
"123abx"
"#1#2
#3#a
#b#x#"
2、然後是具體的manacher演算法,首先給出幾個概念。
3、manacher一共分了四種情況討論。
當遍歷到i時,如果i在r的右邊,則只能採取暴力匹配方式,直接以其為中心查詢回文。
當遍歷到i時,如果i不在r的右邊,則又分為3種情況:
①i關於回文中心c的對稱點i』的回文邊界在c的回文邊界中,則可知i的回文邊界也在c的回文邊界裡,不會再向外擴,解釋如圖:
②i關於回文中心c的對稱點i』的回文邊界在c的回文邊界外(左邊界超出),則可知i的回文右邊界剛好在c的回文右邊界上,不會再向外擴,解釋如圖(圖中左邊是i』,不小心寫錯了):
③i關於回文中心c的對稱點i』的回文邊界在c的回文邊界上(左邊界與左邊界重合),則可知i已有的回文在c的邊界中,但是超過r之後,i是否有能更大的回文,無法得知,只能採用暴力擴的方式,解釋如圖:
4、所以綜上,在**處理上,一共分了4種情況,在情況2、3上其回文半徑就是i』的回文半徑radius[2 * c - i]與r - i其中較小的那乙個。
#include
#include
#include
using
namespace
std;
/*2017/11/18
manacher演算法:
找出字串str中最長的回文子串
*/#if 1
#define max(a,b)(a>b?a:b)
#define min(a,b)(astring newstring(string s)
//都用奇回文解決
string manacher(string s)
if (i + radius[i] > r)
if (radius[i] > imax)
}imax = imax - 1;//imax最後++時多加了乙個1,要減掉,得到原字串的最大回文長度
給定乙個字串str1,只能往str1的後面新增字元變成str2,要求str2
整體都是回文串且最短。
1、只要求出包含了str1中最後乙個字元的最長回文子串s即可。
2、然後將子串s在str1中之前的字元逆序新增到str1末尾即可。
如「abc12321」,包含「1」的最長回文子串是「12321」,將「abc」逆序新增到「abc12321」末尾,變成「abc12321cba」,即為所求的str2。
#include
#include
#include
using
namespace
std;
/*2017/11/18
manacher演算法擴充套件:
給定乙個字串str1,只能往str1的後面新增字元變成str2,要求str2
整體都是回文串且最短。
*/#if 1
#define max(a,b)(a>b?a:b)
#define min(a,b)(astring newstring(string s)
//都用奇回文解決
Manacher演算法及其擴充套件
暴力解最長回文問題 o n 2 o n 2 o n2 manacher演算法o n 回文字串 正著看反著看是一樣的 abccba abcba 存在乙個軸對稱 最長回文字串問題 在乙個字串中找到最長回文字串,而manacher演算法就是去找這個最長回文字串。有啥用?dna序列 回文基因序列有一些生理學...
詳解manacher演算法,及其擴充套件
懂了演算法,改改 即可ac京東18年校園招聘這題。京和東東是好朋友。東東很喜歡回文。回文是指從前往後讀 和從後往前讀是一樣的詞語。京京準備給東東乙個驚喜,先取定 乙個字串s,然後在後面附上0個或者更多個字母形成回文,京 京希望這個回文越短越好。請幫助京京計算他能夠得到的最短 的回文長度。輸入描述 輸...
Manacher演算法總結
所謂回文串,簡單來說就是正著讀和反著讀都是一樣的字串,比如abba,noon等等,乙個字串的最長回文子串即為這個字串的子串中,是回文串的最長的那個。下面介紹manacher演算法的原理與步驟。首先,manacher演算法提供了一種巧妙地辦法,將長度為奇數的回文串和長度為偶數的回文串一起考慮,具體做法...