力扣-最长回文字符串(马拉车算法)
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string longestPailndrome(string newSource)
{
int left = 0, right = newSource.length();//记录字符串的最左最右边界
int center = 0, half_size = 0;//记录最长回文字符串的中心以及半径
int max_right = 0;//记录当前访问位置回文子串右半径最大覆盖范围
int *cover = new int[right];//记录字符串每个位置回文子串的覆盖半径
for (int i = 0; i < newSource.length(); i++)
{
if (i < max_right) //i在max_right的左边
{
cover[i] = min(cover[2 * center - i], max_right - i);
}
else //i在max_right的右边
{
cover[i] = 1;
}
while (i - cover[i] >=left && i + cover[i] < right&&newSource[i - cover[i]] == newSource[i + cover[i]])
{
cover[i] += 1;
}
//更新max_right
if (cover[i] + i - 1 > max_right)
{
max_right = cover[i];
}
//更新center,half_size
if (cover[i] >= half_size)
{
half_size = cover[i];
center = i;
}
}
delete[]cover;
string tempString = newSource.substr(center - half_size + 1, 2 * half_size - 1);
//从tempString中删去字符'#'
tempString.erase(remove(tempString.begin(), tempString.end(), '#'), tempString.end());
return tempString;
}
string changeString(const string &source)
{
int len = 2*source.length()+1;
char *root = new char[len];
root[0] = '#';
unsigned j = 1;
for (unsigned i = 0; i < source.length(); i++)
{
root[j++] = source[i];
root[j++] = '#';
}
string newSource = root;
delete[]root;
return newSource.substr(0,len);
}
int main()
{
string source;
string newSource;
string maxString;
cout << "input a string: ";
cin >> source;
newSource = changeString(source);
maxString = longestPailndrome(newSource);
cout << "source string is: " << source << endl;
cout << "new source string is: " << newSource << endl;
cout << "the longest pailndrome is: " << maxString << endl;
return 0;
}