最長回文子串 Manacher演算法

2022-08-11 10:09:08 字數 2148 閱讀 4090

2018-03-24 14:51:01

在電腦科學中,最長回文子串或最長對稱因子問題是在乙個字串中查詢乙個最長連續子串,這個子串必須是回文。例如「banana」最長回文子串是「anana」。最長回文子串並不能保證是唯一的,例如,在字串「abracadabra」,沒有超過三的回文子串,但是有兩個回文字串長度都是三,是「ada」和「aca」。在一些應用中需要返回全部的最長回文子串(所有字串都是回文,並且不能擴充套件為更大的回文子串)而不是返回其中之一或是最大的回文子串的長度。

[manacher(1975)] 發現了一種線性時間演算法,可以在列出給定字串中從字串頭部開始的所有回文。並且,apostolico, breslauer & galil (1995) 發現,同樣的演算法也可以在任意位置查詢全部最大回文子串,並且時間複雜讀是線性的。因此,他們提供了一種時間複雜度為線性的最長回文子串解法。替代性的線性時間解決 jeuring (1994), gusfield (1997)提供的,基於字尾樹(suffix trees)。

很容易想到的乙個解法是遍歷所有的可能成為最長回文子串的字串,從中挑選出最長的那個。這個解法可以通過遍歷每一可能成為中心的字元開始向兩邊拓展,時間複雜度是o(n ^ 2)。下面介紹的manacher演算法可以在o(n)的時間複雜度完成最長回文子串的求解。

manacher演算法的核心是記錄的當前向右拓展的最長回文的右邊界,利用回文子串的對稱性,對問題進行化簡和轉化。

首先manacher演算法為了消除奇偶性的影響,在原字串中引入了乙個在原串中不會出現的字元,用來將字串長度的奇偶性影響給消除。

用乙個陣列 p[i] 來記錄以字元s[i]為中心的最長回文子串向左/右擴張的長度(包括s[i],也就是把該回文串「對折」以後的長度)。

s  #  1  #  2  #  2  #  1  #  2  #  3  #  2  #  1  #

p  1  2  1  2  5  2  1  4  1  2  1  6  1  2  1  2  1

(p.s. 可以看出,p[i]-1正好是原字串中回文串的總長度)

不妨記最右邊界為right,其中心為id,則有:

如果對稱點的半徑小於right - i + 1,那麼i的半徑和其相等,如果大於,那麼還需要我們進行進一步的判斷。

string manacher(string s) 

int m = new int[sb.length()];

m[0] = 1;

int id = 0;

int right = 0;

for (int i = 1; i < sb.length(); i++)

}int maxr = m[0];

int index = 0;

for (int i = 0; i < m.length; i++)

}string res = "";

for (int i = index - maxr + 1; i < index + maxr - 1; i++)

return res;

}

問題描述:

問題求解:

與上面問題不同的是,這裡的最長回文子串是不連續的,可以使用動態規劃解決。

public int longestpalindromesubseq(string s) 

}return dp[0][s.length() - 1];

}

O n 時間求 最長回文子串 Manacher演算法

回文字串分為奇回文和偶回文,在字串中間插入任意字元使得串變成奇回文串 暴力思想 肯定是找乙個點往兩邊任意擴充套件,遍歷一次,manacher時間為o n 開乙個陣列p記錄 以點i為中點 的最長回文串的半徑,假設前i 1個點的p都已經求出來來,現在考慮p i 如何推導 重點 r是p 1 p i 1 中...

Manacher 最長回文子串

最長回文子串問題 給定乙個字串,求它的最長回文子串長度。如果乙個字串正著讀和反著讀是一樣的,那它就是回文串。下面是一些回文串的例項 12321 a aba abba aaaa tattarrattat 牛津英語詞典中最長的回文單詞 對於最長回文子串問題,最簡單粗暴的辦法是 找到字串的所有子串,遍歷每...

Manacher 最長回文子串

caioj任意門 hz2016評測傳送門 可以的話來一下hz2016評測吧,有的題caioj沒有的我也可以給到資料嘛。include include include include include include include include define maxchar 100000 defin...