【LeetCode Hot 100】5. 最长回文子串

题目描述

考虑回文字符串的特点,从左往右和从右往左读都是一样的,就是说字符串成了“轴对称”。要求一字符串的最长回文子串,我们可以遍历每个字符,求以该字符为轴对称中心的最长对称子串(或者以该字符和下一个字符为中间两个字符的对称子串),在所有这样的子串中长度最长的那个就是我们要找的答案。从回文字符串的对称性来想——这是一种相对直接的想法。

// C++
class Solution {
public:
pair<int, int> expand(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] = expand(s, i, i);
auto [left2, right2] = expand(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);
}
};

回过头来考虑,对于一个子串,如果它是一个回文字符串,那么去除首尾两个字符(当然前提是该子串的长度大于2)它仍然是一个回文子串,反过来说,对于一个回文子串,如果它前后的两个字符相同,那么把这两个新字符加上所形成的新子串也一定是个回文子串。从动态规划的角度去想,我们就找到了这个问题的状态转移方程。如果使用P(i,j)表示字符串s的子串s[i:j]是否是回文子串,则有:

  • P(i,j)=trues[i:j]是回文子串
  • P(i,j)=false,不是

我们可以写出状态转移方程:P(i,j)=P(i+1,j1)(Si==Sj)。显然,这些情况的讨论都是基于子串长度大于2的前提之上,动态规划的边界条件是我们必须考虑的,子串长度为1时,子串一定是回文串,子串长度为2时,当且仅当两个字符相同时子串是个回文串。实际编程时,我们可以通过子串长度和子串起始位置来进行循环。

// C++
class Solution {
public:
string longestPalindrome(string s) {
int len = s.length();
if (len < 2) {
return s;
}
// dp[i][j]表示子串[i...j]是否是回文串
vector<vector<int>> dp(len, vector<int>(len));
for (int i = 0; i < len; i++) {
dp[i][i] = true;
}
int begin = 0, max_len = 1;
for (int L = 2; L <= len; L++) {
for (int i = 0; i < len; i++) {
int j = i + L - 1;
if (j >= len) {
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] && L > max_len) {
max_len = L;
begin = i;
}
}
}
return s.substr(begin, max_len);
}
};

官方题解中提到,从动态规划法的状态转移方程中可以看出,所有状态在状态转移时的可能性都是唯一的,就是说所有状态都是从某个边界状态扩展得到的,这种所谓边界状态就是子串长度为1或2的状态,从这个角度看,可以得到最开始描述的“中心扩展算法”。

posted @   随机生成一个id  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示