題目描述
給定一個字符串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度爲 1000。
示例1:
輸入: "babad"
輸出: "bab"
注意: "aba" 也是一個有效答案。
示例2:
輸入: "cbbd"
輸出: "bb"
解題思路:
使用動態規劃求解
dp[i][j] 表示字符串下標爲 i 和 j 之間爲迴文串。
這道題的核心思想爲,如果一個串是迴文串,那麼在迴文串兩端加上相同的字符,新的字符串同樣爲迴文串。
迴文串有兩種形態:
1、aa 表示迴文串的軸在兩個字符的中間
2、aba 表示迴文串的軸在中間的字符。
算法過程:
- 每一個字符都是一個迴文串
- 判斷長度爲2的字符串是否爲迴文串,即s[i] 和 s[i + 1] 之間是否相等,如aa 就是一個迴文串。
- 判斷長度爲3的字符串是否爲迴文串,即s[0] 和s[ 0 + 3 - 1] ,s[1] 和s[ 1 + 3 - 1],s[2] 和s[ 2 + 3 - 1]之間是否相等。
- 判斷長度爲4的字符串是否爲迴文串,即s[0] 和s[ 0 + 4 - 1] ,s[1] 和s[ 1 + 4 - 1],s[2] 和s[ 2 + 4 - 1]之間是否相等。
- 依次向下判斷,直到長度等於給定字符串的長度爲止。
下面爲AC代碼:
class Solution {
public:
string longestPalindrome(string s) {
if(s.empty() || s.size() == 1){
return s;
}
int len = s.size();
vector< vector<int> > dp(len,vector<int>(len,0));
int start = 0;
int max_length = 1;
for (int i = 0; i < len; i++)
{
dp[i][i] = 1; //表示每一個字母都是迴文數
if(i < len - 1){//注意條件的判斷
if(s[i] == s[i + 1]){
dp[i][i + 1] = 1; //表示連續兩個字母相同,則爲迴文串
start = i;
max_length = 2;
}
}
}
//狀態方程
for (int L = 3; L <= len; L++)
{ //枚舉子串的長度
for (int i = 0; i + L - 1 < len; i++)
{
int j = i + L - 1; //表示子串的右端點
if (s[i] == s[j] && dp[i + 1][j - 1] == 1)
{
dp[i][j] = 1;
start = i;
max_length = L;
}
}
}
return s.substr(start, max_length);
}
};