給定乙個字串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特別特別的差勁。所以我選用中心擴充套件演算法,掃一遍所有節點,把被掃...