給定一個字符串 s,找到 s 中最長的迴文子串。你能夠假設 s 的最大長度爲 1000。
示例 1:
輸入: "babad"
輸出: "bab"
注意: "aba" 也是一個有效答案。
示例 2:
輸入: "cbbd"
輸出: "bb"
複製代碼
首先確認一下什麼是迴文串,aba
屬於迴文串,aa
也屬於迴文串。也就是說迴文串分爲兩種狀況,長度爲奇數是是以最中間的單個字符開始往兩邊擴散。長度爲偶數時須要以最中間的兩個字符開始擴散。所以須要考慮兩種擴散方式。web
代碼以下:數組
// 從l向左擴散和從r向右擴散,返回此時的最長迴文串
string palindrome(string s, int l, int r) {
while(l >= 0 && r < s.size() && s[l] == s[r]) {
l--;
r++;
}
return s.substr(l+1, r-l-1);
}
string longestPalindrome(string s) {
if(s.size() == 0) {
return "";
}
string ans = s.substr(0, 1);
for(int i = 0; i < s.size()-1; i++) {
// 求出從i爲中心開始向左右兩側擴散的最長迴文串
string same = palindrome(s, i, i);
// 求出從i和i+1爲中心開始向左右兩側擴散的最長迴文串
string notSame = palindrome(s, i, i+1);
ans = ans.size() < same.size() ? same : ans;
ans = ans.size() < notSame.size() ? notSame : ans;
}
return ans;
}
複製代碼
時間複雜度爲o(n*n),空間複雜度爲o(1)markdown
數組dp[i][j]
表示字符串s
中[i,j]
區間的子串是否爲迴文串。 咱們能夠肯定的是:url
1. if(i == j) dp[i][j] = true
2. if(i < j) dp[i][j] = false
複製代碼
如何根據dp[i][j]
來求解其餘的值呢?spa
若是s[i]!=s[j],很顯然dp[i][j]=false3d
s[i]==s[j]的狀況下,若是dp[i+1][j-1]=true,此時dp[i][j]=true,此時咱們能夠得出狀態轉移方程:code
dp[i][j] = dp[i+1][j-1] && s[i]==s[j]
複製代碼
根據上圖來看,此時咱們已經能夠肯定dp[i][j]的值了,由於先決條件已經都有了。可是咱們還須要考慮到一點,在dp[i][i+1]的狀況時,即j-i+1=2時,咱們只須要判斷s[i]和s[j]是否相等,例如求解dp[0][1]的時候,dp[1][0]=false,已經失去了參考價值。 代碼以下:orm
string longestPalindrome(string s) {
size_t length = s.size();
int dp[length][length];
int maxLen = 1;
int start = 0;
for(int i = 0; i < length; i++) {
dp[i][i] = true;
}
for(int j = 1; j < length; j++) {
for(int i = 0; i < j; i++) {
if(s[i] != s[j]) {
dp[i][j] = false;
}else {
if(j - i < 2) {
dp[i][j] = true;
}else {
dp[i][j] = dp[i+1][j-1];
}
if(dp[i][j] && j-i+1 > maxLen) {
start = i;
maxLen = j-i+1;
}
}
}
}
return s.substr(start, maxLen);
}
複製代碼
時間複雜度爲o(n* n)
,空間複雜度爲o(n*n)
ci