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.
There is little to say about the O(n^2) solution.
The O(n) solution is by virtue of symmetric property.
if P[ i' ] ≤ R – i,
then P[ i ] ← P[ i' ]
else P[ i ] ≥ P[ i' ]. (Which we have to expand past the right edge (R) to find P[ i ].
If the palindrome centered at i does expand past R, we update C to i, (the center of this new palindrome), and extend R to the new palindrome’s right edge.
So the code is :
class Solution {
public:
string parse(string& s) {
string res = "^#";
for (int i = 0; i < s.length(); ++i)
res += s.substr(i,1) + "#";
res += "$";
return res;
}
string longestPalindrome(string s) {
if (s.length() <= 1)
return s;
string T = parse(s);
int n = T.length();
vector<int> P(n,0);
int i, j, C = 0, R = 0, ii;
for (i = 1; i < n - 1; ++i) {
ii = C*2 - i;
P[i] = (R - i) > 0 ? min(P[ii], R - i) : 0;
while (T[i - 1 - P[i]] == T[i + 1 + P[i]])
++P[i];
if (i + P[i] > R){
R = i + P[i];
C= i;
}
}
int max = 0;
int maxIndex = 1;
for (i = 1; i < n - 1; ++i) {
if (P[i] > max) {
max = P[i];
maxIndex = i;
}
}
return s.substr( (maxIndex - max - 1 ) / 2,max);
}
};
Add some explanations where the complexity is O(n), for the step if (i+P[i] > R):
1. If i+P[i] <= R, the while loop will execute only once because of the sysmetric property
2. If i+P[i]>R, P[i] starts from R-i. The updates for R is linear.