5 最長回文子串

2021-09-12 13:11:05 字數 1961 閱讀 6504

給定乙個字串s,找到s中最長的回文子串。你可以假設s的最大長度為 1000。

示例 1:

輸入: "babad"

輸出: "bab"

注意: "aba" 也是乙個有效答案。

示例 2:

輸入: "cbbd"

輸出: "bb"

思考:

傳統的驗證回文串的方法就是兩個兩個的對稱驗證是否相等,那麼對於找回文字串的問題,就要以每乙個字元為中心,像兩邊擴散來尋找回文串。這個演算法的時間複雜度是o(n*n),要注意奇偶情況需要分開討論。

解法1:

void searchpalindrome(int left,int right,int &start,int &max_len,string s){

while(left >= 0 && right解法2:

定義兩個變數

start

和maxlen

,分別表示最長回文子串的起點跟長度,在遍歷

s中的字元的時候,我們首先判斷剩餘的字元數是否小於等於

maxlen

的一半,是的話說明

maxlen

無法再變長了

,直接break

掉。(因為是從某個字元往兩邊擴充,當剩餘的小於或者等於maxlen的一半時,即使剩下的全部都可以構成,那麼最長也是小於maxlen的,所以可以跳出迴圈了)

class solution {

public:

string longestpalindrome(string s) {

if(s.size() < 2) return s;

int maxlen = 0,start = 0;

int n = s.size();

for(int i =0;i0 && right 我們用兩個變數

left

和right

分別指向當前位置,然後向右遍歷跳過重複項,這個操作很必要,比如對於

noon,i

在第乙個

o的位置,如果我們以

o為最中心往兩邊擴散,是無法得到長度為

4的回文串的,只有先跳過重複,此時

left

指向第乙個o,

right

指向第二個

o,然後再向兩邊擴散。而對於

bob,

i在第乙個

o的位置時,無法向右跳過重複,此時

left

和right

同時指向

o,再向兩邊擴散也是正確的,所以可以同時處理奇數和偶數的回文串,之後的操作就是更新

maxlen

和start了

遇到的幾個錯誤:

1、這裡和上面一種解法不同的地方在於,比較了當前兩項不相等,就是向右遍歷跳過重複項,所以在進行迴圈的時候直接去比較left和right更遠的一項就可以了。

while(left > 0 && right 2、寫成這種形式還是以為迴圈完成之後left和right都向前奪走了一步,實際上這裡比較的就是s[right+1]== s[left-1]),即當前位置的遠處一位,所以left和right是當前位置,直接+1就可以了。

//if(maxlen < right -left -1)

if(maxlen < right -left +1)

3、這個錯誤還是沒有弄清left的位置

// start = left+1;

start = left;

還有一種最簡單的方法:馬拉車演算法,等日後再做吧。

5 最長回文子串

給定乙個字串s,找到s中最長的回文子串。你可以假設s長度最長為1000。示例 輸入 babad 輸出 bab 注意 aba 也是有效答案示例 輸入 cbbd 輸出 bb 方法1 用馬拉車演算法 字串動態規劃 來求最長回文子串時間複雜度可以達到o n 但是部落格裡面有個小失誤 這個id應該不是最大回文...

5 最長回文子串

給定乙個字串s,找到s中最長的回文子串。你可以假設s的最大長度為1000。示例 1 輸入 babad 輸出 bab 注意 aba 也是乙個有效答案。示例 2 輸入 cbbd 輸出 bb class solution def longestpalindrome self,s k len s olist...

5 最長回文子串

給定乙個字串s,找到s中最長的回文子串。你可以假設s的最大長度為 1000。示例 1 輸入 babad 輸出 bab 注意 aba 也是乙個有效答案。示例 2 輸入 cbbd 輸出 bb 這道題比較船艇的應該是dp求法,但鄙人的dp特別特別的差勁。所以我選用中心擴充套件演算法,掃一遍所有節點,把被掃...