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.
Solutions:
1)将sreverse得到revS,然后求s和revS的最长公共字串(不是最长公共子序列)。复杂度为O(N^2),空间也是。但还是总提示超时。在本机上测试500长度用例用时161ms。
class Solution {
private:
string lcstr(string str1, string str2) {
string ret;
int size=str1.size();
int i=0, j=0;
int lowLoc=0, highLoc=0;
// vector<vector<int> > c(size+1, vector<int>(size+1));
int **c=new int*[size+1];
for(i=0; i<=size; ++i) {
c[i]=new int[size+1];
}
for(i=0; i<=str1.size(); ++i) {
c[i][0] = 0;
}
for(j=0; j<=str2.size(); ++j) {
c[0][j] = 0;
}
int maxLength=0;
for(i=1; i<=str1.size(); ++i) {
for(j=1; j<=str2.size(); ++j) {
if(str1[i-1] == str2[j-1]) {
c[i][j] = c[i-1][j-1]+1;
}
else {
c[i][j] = 0;
}
if(c[i][j]>maxLength) {
maxLength=c[i][j];
lowLoc=i;
highLoc=j;
}
}
}
for(i=0; i<=size; ++i) {
delete [] c[i];
c[i]=NULL;
}
delete []c;
return str1.substr(lowLoc-maxLength, maxLength);
}
public:
string longestPalindrome(string s) {
int size=s.size();
// vector<vector<int> > c(size+1, vector<int>(size+1));
// vector<vector<int> > b(size+1, vector<int>(size+1));
string revS;
for(int i=s.size()-1; i>=0; --i) {
revS+=s[i];
}
return lcstr(s, revS);
}
};
2)从某一个字符向两侧对称地扩展,直到不能对称为止。但要注意像“aa”这样的,所以每到一个字符要分别做奇偶扩展。时间复杂度为O(N^2)。
class Solution {
public:
string longExpand(string s, int low, int high) {
//int l=low, h=high;
while(low >= 0 && high<s.size() && s[low]==s[high]) {
--low;
++high;
}
// string ret;
return s.substr(low+1, high-low-1);
// return ret;
}
string longestPalindrome(string s) {
string ret;
string odd, even;
for(int i=0; i<s.size(); ++i) {
odd=longExpand(s, i, i);
even=longExpand(s, i, i+1);
if(odd.size() > ret.size()) {
ret=odd;
}
if(even.size() > ret.size()) {
ret=even;
}
}
return ret;
}
};
Manacher’s Algorithm,O(n)的算法(看不懂)
class Solution{
public:
string longestPalindrome(string s) {
string T = preProcess(s);
int n = T.length();
int *P = new int[n];
int C = 0, R = 0;
int i=0;
for (i = 1; i < n-1; i++) {
int i_mirror = 2*C-i; // equals to i' = C - (i-C)
P[i] = (R > i) ? min(R-i, P[i_mirror]) : 0;
// Attempt to expand palindrome centered at i
while (T[i + 1 + P[i]] == T[i - 1 - P[i]])
P[i]++;
// If palindrome centered at i expand past R,
// adjust center based on expanded palindrome.
if (i + P[i] > R) {
C = i;
R = i + P[i];
}
}
// Find the maximum element in P.
int maxLen = 0;
int centerIndex = 0;
for (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);
}
private:
int min(int a, int b) {
return a<b?a:b;
}
string preProcess(string s) {
int n = s.length();
if (n == 0) return "^$";
string ret = "^";
for (int i = 0; i < n; i++)
ret += "#" + s.substr(i, 1);
ret += "#$";
return ret;
}
};