描述
給定一個字符串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度爲 1000。
輸入: "babad"
輸出: "bab"(注意: "aba" 也是一個有效答案。)
輸入: "cbbd"
輸出: "bb"
dp,除此之外還有一些很炫的解法,這裏只講dp這是一道很好的入門題。
我一向認爲dp第一步不是寫狀態轉移方程,而是把狀態設對。涉及到字符串的子串起碼應該想到二維數組,至於這個代表什麼,就是手感了,設的好方程推 (猜)的輕鬆,否則基本gg;
這裏直接給答案,表示以結尾的串.如果爲迴文串,那麼爲迴文串的條件就是。
初始狀態:dp[i][i]==true; i∈1...n
dp[i][j]=dp[i+1]d[j-1]&&(s[i]==s[j])
畫表理解一下,以babad爲例,填的順序是斜着填的
1 | 0 | 1 | 0 | 0 |
---|---|---|---|---|
1 | 0 | 1 | 0 | |
1 | 0 | 0 | ||
1 | 0 | |||
1 |
上代碼
class Solution {
public:
string longestPalindrome(string s) {
int len=s.length();
vector<vector<bool>> d(len, vector<bool>(len));
int max=1,p=0,flag=1;
for(int i=0;i<len;i++)//初始化
d[i][i]=true;
for(int j=1;j<len;j++)
{
for(int i=0;i<len-j;i++)
{
if(j==1)//長度爲2的串
{
d[i][j+i]=(s[i]==s[i+1]);
if(d[i][i+1]&&flag)//flag用於只記錄第一個長度爲2的迴文串,不用也沒關係
{
max=2;
p=i;
flag=0;
}
}
else//長度大與2的串
{
d[i][j+i]=d[i+1][i+j-1]&&(s[i]==s[i+j]);//轉移方程
if(d[i][j+i]&&j+1>max)
{
max=j+1;
p=i;
}
}
}
}
return s.substr(p, max);//從p開始切割max位
}
};