最長回文子串

2021-10-06 20:41:15 字數 3603 閱讀 3915

題目描述:

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

示例 1:

輸入: 「babad」

輸出: 「bab」

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

示例 2:

輸入: 「cbbd」

輸出: 「bb」

解法一:暴力解法

思路:把字串對應的所有的子串判斷一邊是否是回文串,然後記錄下字串最長的子串的開始和結束位置,然後輸出即可

缺陷:暴力解法,如果字串給的特殊,會超出時間限制

**實現如下:

/* 判斷 從起始位置start到終止位置end的s字串的子串是否是回文串 */

intispalindromic

(char

* s,

int start,

int end)

int i;

int mid =

(end - start +1)

/2+ start;

for(i = start; i < mid; i++)}

return1;

}char

*longestpalindrome

(char

* s)

int slen =

strlen

(s);if(

(slen ==0)

||(slen ==1)

)int i, j;

int flag;

int start =0;

int end =0;

int longest =0;

for(i =

0; i < slen -

1; i++)}

}/* 輸出結果 */

char

* retval =

(char*)

malloc

(end - start +2)

;if(retval ==

null

)memset

(retval,

0x00

, end - start +2)

;for

(i = start; i < end +

1; i++

) retval[end - start +1]

='\0'

;return retval;

}

解法二:動態規劃

思路:對於乙個子串而言,如果它是回文串,並且長度大於 22,那麼將它首尾的兩個字母去除之後,它仍然是個回文串。例如對於字串 「ababa」,如果我們已經知道「bab」 是回文串,那麼 「ababa」 一定是回文串,這是因為它的首尾兩個字母都是 「a」。

那麼我們就可以寫出動態規劃的狀態轉移方程:

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

也就是說,只有 s[i+1:j-1] 是回文串,並且 s 的第 i 和 j 個字母相同時,s[i:j]s[i:j] 才會是回文串。

注意動態規劃搜尋方向

實現**:

char

*longestpalindrome

(char

* s)

else

if(slen ==1)

int dp[

1010][

1010]=

;int i, j, k;

for(i =

0; i <

1010

; i++

)int longest =0;

char

* retval =

(char*)

malloc

(slen +2)

;if(retval ==

null

)memset

(retval,

0x00

, slen +2)

;/* 列舉所有字串 */

for(i = slen -

1; i >(-

1); i--

) retval[longest]

='\0';}

}elseif(

(s[i]

== s[j])&&

((j - i ==1)

||(i - j ==1)

))retval[longest]

='\0';}

}elseif(

(dp[i +1]

[j -1]

==1)&&

(s[i]

== s[j]))

retval[longest]

='\0';}

}}}return retval;

}

解法三: 中心擴充套件演算法

解法思路:邊界情況即為子串長度為 11 或 22 的情況。我們列舉每一種邊界情況,並從對應的子串開始不斷地向兩邊擴充套件。如果兩邊的字母相同,我們就可以繼續擴充套件,例如從 p(i+1,j-1)p(i+1,j−1) 擴充套件到 p(i,j)p(i,j);如果兩邊的字母不同,我們就可以停止擴充套件,因為在這之後的子串都不能是回文串了。

解法實現:

void

expandpalind

(char

* s,

int* start,

int* end)

//中心擴充套件演算法函式

(*start)=(

*start)+1

;(*end)=(

*end)-1

;return;}

char

*longestpalindrome

(char

* s)

else

if(slen ==1)

int i;

int start;

int end;

int start2;

int end2;

int longest =0;

int ansstart =0;

int ansend =0;

int tmp =0;

for(i =

0; i < slen -

1; i++

)//檢查兩個字元為中心的子串

start2 = i;

end2 = i +1;

expandpalind

(s,&start2,

&end2);if

(longest < end2 - start2 +1)

}char

* retval =

(char*)

malloc

(longest +2)

;if(retval ==

null

)memset

(retval,

0x00

, longest +2)

;for

(i = ansstart; i < ansend +

1; i++

) retval[longest]

='\0'

;return retval;

}

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

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,且佔據單獨一行,輸出最長的回文子串 如有多個,輸出,起始位置最...