Manacher演算法及應用

2021-09-25 15:42:06 字數 2578 閱讀 4584

暴力解法:比如給定 "aba",遍歷每個字元,首先來到 a,左右擴,左擴出界,記長度為1。然後來到 b,左右擴,左邊的字元等於右邊,長度加2,再擴出界,記長度為3。再來到 a,右擴出界,記為1。最長就為3。這種暴力擴法的時間複雜度為o(n^2) !

注意當字元數量為偶數時,比如 "abba",按照上述擴法是不能找出回文串的,故對原字元進行統一處理,假設原長為n,處理後的長度為2*n+1,即不論原先是奇回文還是偶回文,處理後都變成奇回文! 例如:"aba" 變成 "#a#b#a#"    "abba" 變成 "#a#b#b#a#"

處理後再按暴力解法求出長度後除以2就得到原字串最長回文子串的長度。

manacher演算法解決該問題可以做到時間複雜度為o(n)!!!

manacher演算法其實是暴力演算法的公升級版,它在擴的過程記錄了幾個資訊,使擴的過程加速了。

記錄了三個資訊:回文半徑陣列,回文中心,回文右邊界。

題目1:給定乙個字串str,返回str中最長回文子串的長度。

//構造manacher字串

public static char manacherstring(string str)

return res;

}public static int maxlcpslength(string str)

char chararr = manacherstring(str);

//回文半徑陣列

int parr = new int[chararr.length];

int c = -1;

int r = -1;

int max = integer.min_value;

for (int i = 0; i != chararr.length; i++)

}//如果擴充區域超過了r,做相應的更新

if (i + parr[i] > r)

//記錄全域性最大值

max = math.max(max, parr[i]);

}return max - 1;

}

題目2:在字串後面新增最少字元,使整個字串都成為回文串。比如 "ab121"  , 輸出 "ab121ba"

該問題等價於找到包含最後乙個字元的最長回文子串,所以想到用manacher演算法!

生成manacher字串函式同上,省略了。

public static string shortestend(string str)

char chararr = manacherstring(str);

int parr = new int[chararr.length];

int c = -1;

int r = -1;

int maxcontainsend = -1;

for(int i=0;i=0 && i+parr[i]<=parr.length-1)else

}if(i+parr[i]>r)

if(r == chararr.length)

}char res = new char[str.length() - maxcontainsend +1];

for(int i=0;i題目3:給定乙個字串 s,你可以通過在字串前面新增字元將其轉換為回文串。找到並返回可以用這種方式轉換的最短回文串。 輸入:"aacecaaa"輸出:"aaacecaaa"  leetcode 214題

public string shortestpalindrome(string s)

char c = manacherstring(s);

int p = new int[c.length];

int c = -1;

int r = -1;

for(int i=0;i=0 && i+p[i]r)

}int maxlen = 1;

for(int i=1;i題目4:給定乙個字串,你的任務是計算這個字串中有多少個回文子串。具有不同開始位置或結束位置的子串,即使是由相同的字元組成,也會被計為是不同的子串。輸入: "abc" 輸出: 3 解釋: 三個回文子串: "a", "b", "c".

輸入: "aaa" 輸出: 6說明: 6個回文子串: "a", "a", "a", "aa", "aa", "aaa".   leetcode 647題

public int countsubstrings(string s)

char c = manacherstring(s);

int p = new int[c.length];

int c = -1;

int r = -1;

int count = 0;

for(int i=0;i=0 && i+p[i]r)

count+=p[i]/2;  //回文半徑就是以該字元為中心回文子串的個數  因為長度為原來的2倍,所以除以2!

}return count;

}

manacher演算法及擴充套件

最近學習了一些演算法,總結一下 manacher演算法和擴充套件。manacher演算法是求乙個字串中,最大回文子串的長度。ifndef manacher h define manacher h manacher演算法 找出字串str中最長的回文子串 define min a,b ab?a b in...

Manacher演算法總結

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

Manacher演算法總結

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