标签:raw bsp 长度 字符串 mamicode 基础上 更新 链接 答案
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法1:最长公共子串
容易想到,回文意味着将这个字串反转,回文的部分一定是公共子串。
子串是一种动态规划的思路。这里借用别人的说明,很详细:

但是这里依然有着一些区别:如果存在abcde...edcba的字串,那么abcde会被认为回文。所以我们需要二次检测来筛除这种问题。
int res[1005][1005];//这个涉及栈的大小问题,本机上开在函数内会超界。
class Solution {
public:
string longestPalindrome(string s) {
string sraw=s;
reverse(s.begin(),s.end());//反转字串
int len=s.length();
int maxlen=0;//最大长度
string ans;//最大回文子串
for(int i=0;i<len;i++)
{
for(int j=0;j<len;j++)
{
if(s[i]==sraw[j])
{
res[i+1][j+1]=res[i][j]+1;
if(res[i+1][j+1]>maxlen)
{
//这里二次判断是否回文。
string tmpans=s.substr(i-res[i+1][j+1]+1,res[i+1][j+1]);
string tmpansraw=tmpans;
reverse(tmpans.begin(),tmpans.end());
if(tmpansraw==tmpans)
{
maxlen=res[i+1][j+1];
ans=tmpans;
}
}
}
else res[i+1][j+1]=0;
}
}
return ans;
}
};
解法2:动态规划。
思路是:遍历字串,然后初始化长度为1和长度为2的回文串。
在回文串的基础上,向左、向右分别多取一个字符,如果相等则构成新的回文串,更新结果。
int res[10050][10050];//不知道为什么1005过不了。。在本机是能过的
class Solution {
public:
string longestPalindrome(string s) {
memset(res,0,10050*10050);
int len=s.length();
string ans=s.substr(0,1);
int maxlen=1;
for(int i=0;i<len;i++)//遍历
{
//初始化一个字符的回文串
int a=i;
int b=i;
res[a][b]=1;
while(a>0&&b<len-1&&res[a][b]==1)//回文且可以向左、向右扩展
{
a--;b++;
if(s[a]==s[b]) res[a][b]=1;//相同则标记回文
if(b-a+1>maxlen&&res[a][b]==1)//更新结果
{
maxlen=b-a+1;
ans=s.substr(a,b-a+1);
}
}
//初始化两个字符的回文串
a=i;
b=i+1;
if(s[a]==s[b]) res[a][b]=1;
if(2>maxlen&&res[a][b]==1)
{
maxlen=2;
ans=s.substr(a,2);
}
while(a>0&&b<len-1&&res[a][b]==1)
{
a--;b++;
if(s[a]==s[b]) res[a][b]=1;
if(b-a+1>maxlen&&res[a][b]==1)
{
maxlen=b-a+1;
ans=s.substr(a,b-a+1);
}
}
}
return ans;
}
};
解法3:Manacher 算法
这个题解提供的我从没见过的算法……有空我会补上。
写给自己:
1.基础要牢。string的基本操作都忘了很多。
2.栈的知识,栈的默认大小为2M或1M,全局才能开到2G。
3.边界条件是最容易犯的错,尽量考虑周到来避免。
标签:raw bsp 长度 字符串 mamicode 基础上 更新 链接 答案
原文地址:https://www.cnblogs.com/xiying159/p/11735428.html