# 最长回文子串的几种解法

142人阅读 评论(0)

根据习惯，首先想一个暴力解法，这个问题的暴力解法思想是这样：遍历每一个子串，判断是否是回文串，并维护一个最长回文起始地址和最大回文长度。求每一个子串时间复杂度O(N^2)，判断子串是不是回文O(N)，两者是相乘关系，所以时间复杂度为O(N^3)。代码如下：

string longestPalindrome(string s) {
int len = s.size();//字符串长度
if (len == 0) return " ";
int maxlen = 0;//最长回文字符串长度
int start;//最长回文字符串起始地址
for (int i = 0; i<len; i++)//起始地址
for (int j = i; j < len; j++)//结束地址
{
int tmp1, tmp2;
for (tmp1 = i, tmp2 = j; tmp1 <= tmp2; tmp1++, tmp2--)//判断是不是回文
{
if (s.at(tmp1) != s.at(tmp2))
break;
}
if (tmp1 > tmp2 && j - i + 1 > maxlen)
{
maxlen = j - i + 1;
start = i;
}
}
return s.substr(start, maxlen);//求子串
}

string longestPalindrome(string s) {
const int length = s.size();
int maxlength = 1;
int start = 0;
bool P[1000][1000] = { false };
for (int i = 0; i<length; i++)//初始化准备
{
P[i][i] = true;
if (i<length - 1 && s.at(i) == s.at(i + 1))
{
P[i][i + 1] = true;
start = i;                           //最后一个长度为2的回文串的起始下标
maxlength = 2;
}
}
for (int len = 3; len<=length; len++)//子串长度
for (int i = 0; i <= length - len; i++)//子串起始地址
{
int j = i + len - 1;//子串结束地址
if (P[i + 1][j - 1] && s.at(i) == s.at(j))
{
P[i][j] = true;
maxlength = len;
start = i;
}
}
return s.substr(start, maxlength);
}

string longestPalindrome(string &s)
{
const int length = s.size();
int maxlength = 1;
int start = 0;
for (int i = 0; i < length; i++)
{
int h = i - 1, k = i, j = i + 1;
while (k >= 0 && j < length && s[k] == s[j])
{
if (maxlength <= j - k + 1)
{
maxlength = j - k + 1;
start = k;
k--;
j++;
}
else
{
k--;
j++;
}
}
h = i - 1, k = i, j = i + 1;
while (h >= 0 && j < length && s[h] == s[j])
{
if (maxlength <= j - h + 1)
{
maxlength = j - h + 1;
start = h;
h--;
j++;
}
else
{
h--;
j++;
}
}
}
return s.substr(start, maxlength);
}

# 解法4：manacher法

string longestPalindrome(string &s)
{
string str;
str += "\$#";
for(int i = 0; i < s.size(); i++)
{
str += s[i];
str += "#";
}
int *p = new int[str.size() + 1];
memset(p, 0, sizeof(p));

int mx = 0, id = 0;
for(int i = 1; i <=  str.size(); i++)
{
if(mx > i)
{
p[i] = (p[2*id - i] < (mx - i) ? p[2*id - i] : (mx - i));
}
else
{
p[i] = 1;
}

while(str[i - p[i]] == str[i + p[i]])
p[i]++;

if(i + p[i] > mx)
{
mx = i + p[i];
id = i;
}

}
int max = 0, ii;
for(int i = 1; i < str.size(); i++)
{
if(p[i] > max)
{
ii = i;
max = p[i];
}
}

max--;

int start = ii - max ;
int end = ii + max;
char buf[1000];
memset(buf,'\0',1000);
int k=0;
for(int i = start; i <= end; i++)
{
if(str[i] != '#')
{
buf[k++] = str[i];
}
}
delete  p;
return buf;
}

0
0

个人资料
• 访问：143次
• 积分：11
• 等级：
• 排名：千里之外
• 原创：1篇
• 转载：0篇
• 译文：0篇
• 评论：0条
文章分类
文章存档