最長回文子串

2021-07-03 13:45:20 字數 1637 閱讀 8265

題意:給定乙個字串s,找出該字串中最長的回文子串。

字串如「abcba」,」abbbba」這樣呈中心對稱的子串稱為回文串。該題目是乙個老題了,有多種不同的解法,我整理一下方便以後查詢。

這個方法是我們看到這個題目後最容易想到的方法,暴力搜尋所有的子串,判斷每個子串是否是回文串;我們用乙個二維空間記錄已計算過的子串是否為回文串,這樣之後針對每個新子串進行判定的時候可以利用之前記錄資訊輔助判斷。基本的動規方程如下:

該方法的**很簡單,可去網上查詢,最終的時間複雜度是o(n^2).

對於回文子串,我們還需要想到其性質:字串關於中心位置對稱。那麼可以看到若子串s[3,5]不是回文串的話,那麼s[2,6],s[1,7]等必然不是回文串,利用該性質我們可以省去一些不必要的比較計算。

相對於第一種方法,肯定有著更好的實際執行效果。

參考**如下:

string longestpalindrome(string s) 

// 向左右兩邊擴張.

int new_len = k - j + 1;

if (new_len > max_len)

}return s.substr(min_start, max_len);

}

思路即是 從字串的第乙個字元做中心點開始,不斷向串的兩邊擴張直到不能擴張,之後將中心點右移,不斷重複操作;過程中記錄下回文串起始點和回文長度。

當然該方法的最壞的時間情況仍然是o(n^2). 對於s=」aaaaaaaa」這樣的特殊字串,每個中心點都會左右擴張到字串的邊緣,因此此時時間複雜度為o(n^2).

該演算法從網上學來,充分巧妙的利用了回文串的性質,能保證線性的時間複雜度。

演算法思路:

演算法過程中 同時記錄最大回文子串的長度和起始點。

string longestpalindrome(string s) 

else

p[i] =0;

while(i-1-p[i]>=0 && i+1+p[i]size() && t[i+1+p[i]] == t[i-1-p[i]])

p[i]++;

if(i+p[i]>boundary)

if(p[i]>maxlen)

}return s.substr((rescenter - maxlen)/2, maxlen);

}

時間複雜度分析:boundary在整個演算法過程中是一直向右移動的,並且每次移動都是因為新的對稱字元的比較,通過聚合分析方法來考慮**段

while(i-1-p[i]>=0 && i+1+p[i]

size() && t[i+1+p[i]] == t[i-1-p[i]])

p[i]++;

這裡的**執行 引起了boundary的向右擴張,而boundary最大只能是n。所以整個演算法的時間複雜度是線性的,即o(n)。

本文分析了三種不同的求解最長回文子串的方法,希望能給讀本文的人一點收穫和思考。

最長回文子串 最長回文子串行

1.最長回文子串行 可以不連續 include include include include using namespace std 遞迴方法,求解最長回文子串行 intlps char str,int i,int j intmain include include include using n...

最長回文子串

描述 輸入乙個字串,求出其中最長的回文子串。子串的含義是 在原串連續出現的字串片段。回文的含義是 正著看和倒著看是相同的,如abba和abbebba。在判斷是要求忽略所有的標點和空格,且忽略大小寫,但輸出時按原樣輸出 首尾不要輸出多餘的字串 輸入字串長度大於等於1小於等於5000,且單獨佔一行 如果...

最長回文子串

輸入乙個字元,求出其中最長的回文子串。子串的含義是 在元串中連續出現的字串片段。回文的含義是 正看和倒看相同,如abba和yyxyy,在判斷時候應該忽略所有的空格和標點符號,且忽略大小寫,但輸出應該保持原樣,輸入的字元長度不超過5000,且佔據單獨一行,輸出最長的回文子串 如有多個,輸出,起始位置最...