半对
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
思路一:翻转字符串法。
1.将整个字符串反转,然后判断原始的字符串是否在反转的字符串中出现。
2.只是出现还不够,还要验证该字符串是否是回文的。
class Solution {
public:
string longestPalindrome(string s) {
if (s.length()==1) return s;
string rev=s;
std::reverse(rev.begin(),rev.end()); //reverse函数,将字符串反转
string res;
if (rev==s) return s;
int len=0;
for (int i=0; i<s.length(); i++)
{
string tmp;
for (int j=i; j<s.length(); j++)
{
tmp=tmp+s[j];
if(len>tmp.length())
continue;
else if (rev.find(tmp)!=-1)
{
string q=tmp;
std::reverse(q.begin(),q.end());
if(q==tmp)
{
len=q.length();
res=tmp;
}
}
else
break;
}
}
return res;
}
};
思路二:动态规划法.
1.定义一个(len, len)的二维数组,数组的(i,i)是1,因为单个字符是回文字符。
2.如果s[i]==s[i+1],则是两个连续的字符,也构成回文。
3.从长度为三开始扫描,如果s[i]==s[j]&&d[i+1][j-1]==1,则构成一个新的回文字符串。
class Solution {
public:
string longestPalindrome(string s) {
int len= s.length();
if (len==0||len==1) return s;
int start=0;
int max=1;
vector<vector<int>> dp(len, vector<int>(len)); //注意vector<vector<int>>的初始化。
for (int i=0; i<len; i++)
{
dp[i][i]=1;
if (i<len-1&&s[i]==s[i+1])
{
dp[i][i+1]=1;
max=2;
start=i;
}
}
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;
max=l;
start=i;
}
}
}
return s.substr(start,max);
}
};