思想:manacher演算法
該演算法避免了我們在遍歷過程中對回文字串是奇數長度還是偶數長度分別都要進行判斷的操作,做法就是在開始結束以及每個字元之間新增特殊字元,以1221為例,進行填充之後就變成#1#2#2#1#,以121為例,進行填充之後就變成#1#2#1#,這樣做的好處是,填充之後字串的長度都成了奇數,這樣我們在遍歷的過程中對於每乙個位置的判斷都轉換成了同樣的操作,並不需要關心最後我們得到的回文串到底是奇數長度還是偶數長度了;
實現:要想實現的話,這裡用到乙個輔助陣列和兩個輔助變數:
radius[ ]:輔助陣列,表示每一位置用來表示該位置上的回文半徑值
bound:輔助變數,表示記錄回文半徑即將到達的位置
index:輔助變數,表示bound發生更新的時候,對應bound的回文中心的位置
在我們想要計算第 i 位置上的最大回文串長度時,有兩種情況需要考慮:
(1) i 正好在bound當前回文串邊界內部,這時候就是manacher演算法的精髓了,見下圖,分三種情況來考慮,其中 i' 是 i 相對於index的對稱點
為了程式設計方便,我們會把這三種情況中 i 位置應該開始遍歷的初始位置計算成為是上圖三種情況中的最小值;
(2)第二種情況的話,i 位於bound邊界之外,那麼這時候manacher演算法
是沒法起作用的,因為此時將要遍歷的地方之前是沒有遍歷過的,只能乖乖從當前位置一步一步遍歷了,對應於下圖這種情況:
程式**:
/**
* 採用manacher演算法實現求最長回文子串
* radius陣列用來儲存每個位置上可以向左或者向右最大擴充的半徑
* bound表示回文半徑即將到達的位置(是下乙個位置)
* index表示bound更新的時候對應的回文中心的位置
* @author 扇扇來馳
* */
public class getlongestpalindrome
public static int getlongestpalidrome(string str1)
else
radius[i] = 1;
for(int j = 0;i+radius[i]+j < str.length() && i-radius[i]-j >= 0;)
if(i+radius[i] > bound)
}return getmax(radius)-1; }
/*** 在字串中新增特殊字元
* @param str
* @return
*/public static string changestring(string str)
result = result+"#";
return result; }
public static int getmax(int arr)
return max;
}}
leetcode每日一練 最長回文子串 java
題目 給定乙個字串s,在s中找到最長的字串。您可以假設s的最大長度為1000。example 1 輸入 babad 輸出 bab 注 aba 也是乙個有效的答案。思想 中心結點法,就是遍歷整個字串,將每個點分別都設為中心結點,然後第二個遍歷是分別對設定的中心向左右擴充套件,所以複雜度為o n 2 比...
求最長回文子串
求最長回文子串,大概有以下幾種方法 1 錯誤!先翻轉再求最長公共子串 例如 abcdafdcba abcd x 即原串中包含翻轉串的子串時 2 暴力 遍歷每個字串,然後判斷是否是回文子串並記錄最長資訊 時間複雜度o n 3 3 動態規劃 時間複雜度o n 2 空間複雜度o n 2 dp i j 表示...
求最長回文子串
1.第一種方法 o n 2 動態規劃,用s i j 表示從i到j是最長回文字串,用乙個table i j 記錄字串從i到j是否為回文,這樣的話,從底部向上,table i i true 另外如果s i s i 1 則table i i 1 true,然後長度從3開始,如果s i 1 s j 1 則就...