第一次纯自己debug写出的medium,用的中心扩散法。没有力气写解释了,注释写了很多。这道题还可以用动态规划,但我现在还不是很熟练,也许以后可以更新一下。代码如下:
class Solution {
public:
string longestPalindrome(string s)
{
int len = s.length(); //记录字符串长度
if(len == 1) return s; //如果字符串中只有一个字符,则返回原本字符
//对回文分为两种情况,一种为回文中心为两个字符,这里用double表示,一种只有一个字符,用single表示
long doublemaxrange = INT_MIN; //中心两个字符,用于记录回文臂长
long doublemaxMidpoint = INT_MIN; //中心两个字符,用于记录回文左中心点
long singlemaxrange = INT_MIN; //中心一个个字符,用于记录回文臂长
long singlemaxMidpoint = INT_MIN; //中心一个个字符,用于记录回文中心点
for(int i = 0; i < len - 1; ++i) //对字符串每一个字符,直至倒数第二个,进行遍历循环
{
if(s[i] == s[i+1]) //若当前字符与下一个字符相同,则它则可以是一个中心两个字符的回文
{
for(int k = 0; k < min(i+1 , len - i); ++k)
{
if(s[i - k] == s[i + k + 1]) //向外拓宽,检查中心外侧是否相同
{
if(k > doublemaxrange) //相等时,记录臂长,并保留最长臂长
{
doublemaxrange = k;
doublemaxMidpoint = i;
}
}
else break; //当外侧字符不相同是,停止本次循环
}
}
for(int k = 0; k < min(i+1 , len - i); ++k) //对当前遍历到的字母做单中心字符检查,原理与双字符相同
{
if(s[i - k] == s[i + k])
{
if(k > singlemaxrange)
{
singlemaxrange = k;
singlemaxMidpoint = i;
}
}
else break;
}
}
long doublelen = doublemaxrange * 2 + 1; //检查双字符回文与单字符回文的最长长度
long singlelen = singlemaxrange * 2;
string ans;
if(doublelen > singlelen) //选择最长的回文进行显示
{
for(int i = doublemaxMidpoint - doublemaxrange; i < doublemaxMidpoint + doublemaxrange + 2; ++i)
{
ans += s[i];
}
}
else
{
for(int i = singlemaxMidpoint - singlemaxrange; i < singlemaxMidpoint + singlemaxrange + 1; ++i)
{
ans += s[i];
}
}
return ans;
}
};