leetcode 5.最長迴文子串
阿新 • • 發佈:2018-12-25
leetcode 5:最長迴文子串:給定一個字串 s
,找到 s
中最長的迴文子串。你可以假設 s
的最大長度為 1000。(難度:中等)
迴文:把相同的詞彙或句子 ,在下文中調換位置或顛倒過來,產生首尾迴環的情趣,叫做迴文,也叫回環 。
示例 1:
輸入: "babad"
輸出: "bab"
注意: "aba" 也是一個有效答案。
示例 2:
輸入: "cbbd"
輸出: "bb"
1、暴力法
最容易想到的就是暴力破解,求出每一個子串,之後判斷是不是迴文,找到最長的那個。
求每一個子串時間複雜度O(N^2),判斷子串是不是迴文O(N),兩者是相乘關係,所以時間複雜度為O(N^3)。
class Solution { public: string longestPalindrome(string s) { int length = s.size(); int maxlen = 0; int start = 0; for(int i = 0; i<length; ++i){ for(int j=i+1; j<length; ++j){ int m = 0, n = 0; for(m = i, n = j; m < n; ++i, --j){ if(s.at(m) != s.at(n)) break; } if(m >= n && j-i > maxlen){ maxlen = j=i-1; start = i; } } } if(maxlen > 0) return s.substr(start, maxlen); return NULL; } };
2、動態規劃
動態規劃問題是面試題中的熱門話題,如果要求一個問題的最優解(通常是最大值或者最小值),而且該問題能夠分解成若干個子問題,並且小問題之間也存在重疊的子問題,則考慮採用動態規劃。
使用動態規劃特徵:
1. 求一個問題的最優解
2. 大問題可以分解為子問題,子問題還有重疊的更小的子問題
3. 整體問題最優解取決於子問題的最優解(狀態轉移方程)
4. 從上往下分析問題,從下往上解決問題
5. 討論底層的邊界問題
迴文字串的子串也是迴文,比如P[i,j](表示以i開始以j結束的子串)是迴文字串,那麼P[i+1,j-1]也是迴文字串。這樣最長迴文子串就能分解成一系列子問題了。這樣需要額外的空間O(N^2),演算法複雜度也是O(N^2)。
首先定義狀態方程和轉移方程:
P[i,j]=0表示子串[i,j]不是迴文串。P[i,j]=1表示子串[i,j]是迴文串。
string longestPalindrome(string s)
{
if (s.empty()) return "";
int len = s.size();
if (len == 1)return s;
int longest = 1;
int start=0;
vector<vector<int> > dp(len,vector<int>(len));
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;
longest=2;
}
}
}
for (int l = 3; l <= len; l++)//子串長度
{
for (int i = 0; i+l-1 < len; i++)//列舉子串的起始點
{
int j=l+i-1;//終點
if (s[i] == s[j] && dp[i+1][j-1]==1)
{
dp[i][j] = 1;
start=i;
longest = l;
}
}
}
return s.substr(start,longest);
}