題目描述:
給定乙個字串 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,且佔據單獨一行,輸出最長的回文子串 如有多個,輸出,起始位置最...