难度:中等
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
思路1:暴力求解,分为奇偶数个字符。分别对每个字符为中心往两边进行判断,单个为中心和两个为中心。
手写第一版,很繁琐。
//暴力求解
class Solution {
public:
string longestPalindrome(string s) {
if(s.size()<=1) return s;
int len=0;
string ans;
for(int i=0;i<s.size();i++)
{
searchPalindrome(s,i,len,ans);
searchPalindrome(s,i,i+1,len,ans);
}
if(len==0) ans=s[0];
return ans;
}
void searchPalindrome(string s, int middle, int & len, string & ans)
{
int left=middle-1,right=middle+1;
if(left<0 || right>s.size()-1) return;
while(left>=0 && right<s.size())
{
if(s[left]!=s[right])
{
left++;
right--;
break;
}
if(left==0 || right==s.size()-1) break;
--left;
++right;
}
int cur=right-left+1;
if(cur>len)
{
len=cur;
ans.assign(s,left,cur);
}
}
void searchPalindrome(string s, int left, int right, int & len, string & ans)
{
if(left<0 || right>s.size()-1) return;
if(s[left]!=s[right]) return;
while(left>=0 && right<s.size())
{
if(s[left]!=s[right])
{
left++;
right--;
break;
}
if(left==0 || right==s.size()-1) break;
--left;
++right;
}
int cur=right-left+1;
if(cur>len)
{
len=cur;
ans.assign(s,left,cur);
}
}
};
修改第二版,将两个函数合并成一个。
class Solution {
public:
string longestPalindrome(string s) {
if(s.size()<2) return s;
int len=1, size=s.size(), start=0;
for(int i=0;i<size;)
{
int left=i,right=i;
while(right<(size-1) && s[right]==s[right+1]) right++;
i = right+1;
while(left>0 && right<size-1 && s[right+1]==s[left-1])
{
left--;
right++;
}
if((right-left+1)>len)
{
len = right-left+1;
start=left;
}
}
return s.substr(start,len);
}
};
可以进一步根据剩余字符串长度是否小于当前最大长度的一半优化算法。即在for循环里,首先判断
if((size-i)<=len/2) break;