Longest Palindromic Substring
Question
insight
dp
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Solution {
public:
string longestPalindrome(string s) {
int n = s.size();
if(n < 2) {
return s;
}
vector<vector<int>> dp(n, vector<int>(n));
int begin = 0, maxLen = 1;
//init when len=1
for(int i = 0; i < n; ++i) {
dp[i][i] = true;
}
for(int l = 2; l <= n; ++l) {
for(int i = 0; i < n; ++i) {
int j = l + i - 1;// len = j - i + 1;
if(j >= n) {
break;
}
if(s[i] != s[j]) {
dp[i][j] = false;
}
else {
if(j - i < 3) {
dp[i][j] = true;
}
else {
dp[i][j] = dp[i+1][j-1];
}
}
if(dp[i][j] && j - i + 1 > maxLen) {
maxLen = j - i + 1;
begin = i;
}
}
}
return s.substr(begin, maxLen);
}
};
Center Expansion
class Solution {
public:
pair<int, int> expandAroundCenter(const string& s, int left, int right) {
while (left >= 0 && right < s.size() && s[left] == s[right]) {
--left;
++right;
}
return {left + 1, right - 1};
}
string longestPalindrome(string s) {
int start = 0, end = 0;
for (int i = 0; i < s.size(); ++i) {
auto [left1, right1] = expandAroundCenter(s, i, i);
auto [left2, right2] = expandAroundCenter(s, i, i + 1);
if (right1 - left1 > end - start) {
start = left1;
end = right1;
}
if (right2 - left2 > end - start) {
start = left2;
end = right2;
}
}
return s.substr(start, end - start + 1);
}
};
Manacher-Algorithm
class Solution {
public:
int expand(const string& s, int left, int right) {
while (left >= 0 && right < s.size() && s[left] == s[right]) {
--left;
++right;
}
return (right - left - 2) / 2;
}
string longestPalindrome(string s) {
int start = 0, end = -1;
string t = "#";
for (char c: s) {
t += c;
t += '#';
}
t += '#';
s = t; // make a possibly even string an odd one.
vector<int> arm_len;
int right = -1, j = -1;
for (int i = 0; i < s.size(); ++i) {
int cur_arm_len;
if (right >= i) {
int i_sym = j * 2 - i;
int min_arm_len = min(arm_len[i_sym], right - i);
cur_arm_len = expand(s, i - min_arm_len, i + min_arm_len);
} else {
cur_arm_len = expand(s, i, i);
}
arm_len.push_back(cur_arm_len);
if (i + cur_arm_len > right) {
j = i;
right = i + cur_arm_len;
}
if (cur_arm_len * 2 + 1 > end - start) {
start = i - cur_arm_len;
end = i + cur_arm_len;
}
}
string ans;
for (int i = start; i <= end; ++i) {
if (s[i] != '#') {
ans += s[i];
}
}
return ans;
}
};
Last modified: 06 February 2024