原题链接:https://leetcode-cn.com/problems/longest-palindromic-substring/
暴力解法: 时间复杂度: O(n2) 空间复杂度: O(n2)
解题思路:
枚举左节点和右节点,通过之前的状态转移
string longestPalindrome(string s) {
int n = s.size();
if(n <= 1){
return s;
}
int maxs = 0;
int begin = 0;
vector<vector<int>> dp(n,vector<int> (n));
for(int len = 1; len <= n; len ++){
for(int i = 0;i + len - 1 < n; i++){
int j = i + len - 1;
if(s[i] != s[j]){
dp[i][j] = 0;
}else{
if(j - i < 3)
dp[i][j] = 1;
else
dp[i][j] = dp[i+1][j-1];
}
if(dp[i][j] && j - i + 1 > maxs){
maxs = j - i + 1;
begin = i;
}
}
}
return s.substr(begin,maxs);
}
Manacher算法:时间复杂度: O(n) 空间复杂度: O(n)
class Solution {
public:
int Get_armlen(const string &s,int left,int right){
int cnt = 0;
while(left >= 0 && right < s.size() && s[left] == s[right]){
left--;right++;
}
return (right - left - 2) / 2;
}
string longestPalindrome(string s) {
int st = 0 ,ed = -1;
string s2;
s2 += "#";
for(auto ch : s){
s2 += ch;
s2 += "#";
}
s = s2;
int right = -1,j = -1;
vector<int> arm_len;
for(int i = 0;i < s.size();i ++){
int cnt_armlength;
if(i <= right){
int k = 2 * j - i;
int min_armlengt = min(arm_len[k],right - i);
cnt_armlength = Get_armlen(s,i - min_armlengt,i + min_armlengt);
}else{
cnt_armlength = Get_armlen(s,i,i);
}
arm_len.push_back(cnt_armlength);
if(i + cnt_armlength > right){
right = i + cnt_armlength;
j = i;
}
if(ed - st < 2 * cnt_armlength + 1){
st = i - cnt_armlength;
ed = i + cnt_armlength;
}
}
string ans;
for(int i = st ;i <= ed; i++){
if(s[i] != '#') ans += s[i];
}
return ans;
}
};