Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
O(n^2)的方法:44 milli secs
class Solution {
public:
string longestPalindrome(string s) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
int nSize = s.size();
if (nSize == NULL) return "";
int length = 1;
const char* ps = s.c_str();
const char* pstart = ps;
const char* result = ps;
while(*ps != '\0')
{
// odd
const char *p1 = ps - 1;
const char *p2 = ps + 1;
while(p1 >= pstart && *p2 != '\0' && *p1 == *p2)
{
--p1;
++p2;
}
int tmp = p2 - p1 - 1;
if (tmp > length)
{
length = tmp;
result = p1 + 1;
}
// even
p1 = ps;
p2 = ps + 1;
while(p1 >= pstart && *p2 != '\0' && *p1 == *p2)
{
--p1;
++p2;
}
tmp = p2 - p1 - 1;
if (tmp > length)
{
length = tmp;
result = p1 + 1;
}
++ps;
}
return s.substr(result - pstart, length);
}
};
O(n),但测试时间和上一种方法竟然一样,奇怪。(Manacher’s Algorithm)
class Solution {
public:
string preProcess(string s)
{
int n = s.size();
if (n == 0) return "^$";
string ret = "^";
for (int i = 0; i < n; i++)
ret += "#" + s.substr(i, 1);
ret += "#$";
return ret;
}
string longestPalindrome(string s) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
string T = preProcess(s);
int n = T.size();
int *P = new int[n];
// C表示i之前子串中的最大回文子串中心的位置
// R为C+P[C],也就是最大回文子串向右扩展的边界
int C = 0, R = 0;
for (int i = 1; i < n-1; i++)
{
int i_mirror = 2*C-i; // i_mirror是i关于C的对称点
// P[i] = (R > i) ? min(R-i, P[i_mirror]) : 0;
// 当前i在最大回文子串的边界内
if (R > i)
{
// 两者区间取小的,i+P[i_mirror]的范围和R的方位
if (R-i < P[i_mirror])
P[i] = R-i;
else
P[i] = P[i_mirror];
}
else
P[i] = 0;
while (T[i + 1 + P[i]] == T[i - 1 - P[i]])
P[i]++;
if (i + P[i] > R)
{
C = i;
R = i + P[i];
}
}
// 找出p[i]中最大的
int maxLen = 0;
int centerIndex = 0;
for (int i = 1; i < n-1; i++)
{
if (P[i] > maxLen)
{
maxLen = P[i];
centerIndex = i;
}
}
delete[] P;
return s.substr((centerIndex - 1 - maxLen)/2, maxLen);
}
};