求最長回文子串

2021-06-22 14:46:12 字數 1560 閱讀 3205

求最長回文子串,大概有以下幾種方法:

1、(錯誤!)先翻轉再求最長公共子串 例如:abcdafdcba -> abcd (x) 即原串中包含翻轉串的子串時

2、暴力(遍歷每個字串,然後判斷是否是回文子串並記錄最長資訊),時間複雜度o(n^3)

3、動態規劃  時間複雜度o(n^2) 空間複雜度o(n^2)

dp[i][j] 表示下標i到j是否為回文子串,初始狀態和狀態轉換方程如下:

dp[i][i] = true, dp[i][i+1] = (s[i] == s[i+1])

dp[i][j] = (dp[i+1][j-1] && s[i] == s[j])

4、遍歷每個中心點和每兩個中心點(相鄰相等時),向左右兩個方向擴充套件時間複雜度o(n^2) 空間複雜度o(1)

5、manacher演算法時間複雜度o(n)

主要包含以下幾個步驟:(以waabwswfd為例)

原串:         w      a    a     b      w    s    w     f      d

新串:        ^#  w  # a # a #  b  # w # s # w #  f  # d #

輔助陣列p: 1  2  1 2 3 2 1  2  1  2 1 4 1 2 1  2 1 2 1

在原串中間插入#,巧妙的將回文子串變成以中間元素為對稱的子串。

輔助陣列p[i] 代表的是以i為中心的回文的半徑,不難看出在原串中能達到的最長回文子串長度為p[i] - 1

計算p[i]時,用mx記錄當前最長回文子串能到達的最右位置,id記錄當前能達到最長回文子串的中心(mx = id + p[id])

有公式:p[i] >= min(p[j], mx - i)

int j = 2 * id - i;// j為以id為中心i的對稱點

if(mx > i)

p[i] = min(p[j], mx - i);

else

p[i] = 1;

while(destring[i - p[i]] == destring[i + p[i]])

p[i]++;

即以id為中心的回文子串和以j為中心的子串重疊的部分,又對稱性可知p[i]至少是那麼長,後面手動擴充套件即可。

最後遍歷p即可找到最長回文子串。

**如下:([leetcode] longest palindromic substring)

class solution 

}int maxlength = 0, center = 0;

for(int i = 0; i < destring.length() - 1; ++i)

}delete p;

return s.substr((center + 1 - maxlength) / 2, maxlength - 1);

}private:

string decoratestring(string s)

return destring;

}};

6、字尾陣列 具體見july大神的文章

字尾樹

求最長回文子串

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 則就...

求最長回文子串

利用中心擴充套件法求最長回文子串演算法複雜度為o 待改進 manacher方法,manacher 法將所有的字串全部變成奇數個字元。思想 回文子串一定是個中心對稱的圖形,有的對稱中心是乙個字母比如abcba,有的是對稱中心是兩個字母比如abba。所以需要分開進行 程式中會有體現 利用回文子串的這一特...

求最長回文子串

要求 給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為1000。示例 1 輸入 babad 輸出 bab 注意 aba 也是乙個有效答案。示例 2 輸入 cbbd 輸出 bb 解法一 暴力求解法 思想 反轉 s,使之變成 s 找到 s 和 s 之間最長的公共子串,這也必然是...