# Several methods of finding the longest palindrome substring

Posted by kripz on Wed, 29 Jan 2020 13:52:04 +0100

# 1, Violent solution O(n3)O(n^3)O(n3)

\quad directly enumerates the two ends i,ji,ji,j, and then determines whether the string s[i,,,j]s[i,,,j]s[i,,,j] s [I,,, J] is a palindrome string.

class Solution {
public:
string longestPalindrome(string s) {
int n = s.length();
pair<int, int> p = {0, 0};  // Record the starting position and length of palindrome string
for(int i = 0; i < n; i++)
{
if(p.second == n) break;  // The whole string is palindrome string, which can be exited directly
for(int j = i; j < n; j++)
{
int l = i, r = j;
while(l <= r && s[l]==s[r])  l++, r--;
if(l >= r && j-i+1 > p.second) p = {i, j-i+1};
}
}
return s.substr(p.first, p.second);
}
};


\The spatial complexity of quad is O(1)O(1)O(1).

# 2, Optimized violence O(n2)O(n^2)O(n2)

\quad starts from each character and moves along the left and right respectively until the left and right characters exit at different times. For example, s = "dabac d", starting from the third letter b, going left and right one step to get a, indicating that the current aba is palindrome string, going left to get d, going right to get c, different, indicating that dabac is not palindrome string, ending the cycle. We can get that the longest palindrome string centered on the third letter b is aba. In the above case, the longest palindrome string is odd. In the case of s"baabd", the longest palindrome string is baab, and the length is odd. An additional character t = "b × a × a × b × c" can be inserted between each two characters, so the two cases are unified.

class Solution {
public:
string longestPalindrome(string s) {
string t = "";
for(int i = 0; i < s.length(); i++)
t += s[i], t += '#';
int n = t.length() - 1;
string res = "";
for(int i = 0; i < n; i++)
{
// It is impossible to find the longest palindrome string longer than the current one, break ahead
if(res.length() > n-i) break;
string temp = "";
int l = i, r = i;
while(l>=0 && r<n && t[l]==t[r]) l--, r++;
for(int j = l+1; j <= r-1; j++)
if(t[j]!='#') temp += t[j];
if(temp.length() > res.length()) res = temp;
}
return res;
}
};


# 3, Dynamic planning O(n2)O(n^2)O(n2)

\quadp[i][j] indicates whether the string from I to j i s a palindrome string. p[i][j] is initialized to false. If and only if s [i] = = s [J] & & J-I < 3 or s [i] = = s [J] & & p[i+1][j-1] = = true, p[i][j]=true. Because we need to know the state of p[i+1][j] to judge the state of p[i][j], we need to first traverse I from large to small. At the same time, the start position and length of the palindrome string are recorded for updating.

class Solution {
public:
string longestPalindrome(string s) {
int n = s.length();
if(n<2) return s;
bool dp[n][n] = {false};
pair<int, int> p = {0, 0};  // Record the starting position and length of palindrome string
for(int i = n-1; i >= 0; i--)
for(int j = i; j < n; j++)
{
if(s[i]==s[j] && (j-i<3 || dp[i+1][j-1]==true))
{
dp[i][j] = true;
if(j-i+1 > p.second) p = {i, j-i+1};
}
}
return s.substr(p.first, p.second);
}
};


# 4, manacher algorithm O(n)O(n)O(n)

\quad is similar to the second method, but we take more efficient measures when we count the longest palindrome string centered on a certain letter. This is the "horse drawn cart" algorithm.

struct P{
int l, r, len; // Start, end, actual length
};
class Solution {
public:
string longestPalindrome(string s) {
if(s.length() < 2) return s;
string t;
for(auto c: s) t += c, t += '#';
int n = t.length() - 1;
int d[n] = {0};
P p = {0, 0, 0}; // {start position, length}
for(int i = 0, l = 0, r = -1; i < n; i++)
{
int k = (i > r) ? 1 : min(d[l + r - i], r - i);
while(0 <= i - k && i + k < n && t[i - k] == t[i + k]) k++;
d[i] = k--;
int start = i - d[i] + 1;
int len = t[start] == '#' ? (d[i] * 2 - 2) / 2 : (d[i] * 2) / 2;
if(len > p.len) p = {start, i + d[i] - 1, len};
if(i + k > r) l = i - k, r = i + k;
}
string res = "";
for(int i = p.l; i <= p.r; i++) if(t[i] != '#') res += t[i];
return res;
}
};


\quad actually has a string hash, and then uses bisection to find the longest boundary around each letter that can form a palindrome string. The time complexity is O(nlogn)O(nlogn)O(nlogn). Interested partners can try it~

220 original articles published, 92 praised, 70000 visitors+