![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/eae0f9209b160d5edee228455f98bac0.png)
0 前言
本题和《Leetcode|线性序列|647. 回文子串》 很像,只是转而输出最长回文子串,但方法相同,单独对比每次回文子串大小,取最大和对应子串起始索引即可
1 动态规划
【dp
数组含义】表示区间范围s[i,j]
的子串是否是回文子串,如果是dp[i][j]
为true
,否则为false
当s[i] == s[j]
时有如下两种情况
- 共
1
个字符或2
个相邻字符 - 多个字符(>2)则需要判断
s[i+1, j-1]
内是否回文串
class Solution {
public:
string longestPalindrome(string s) {
int size = s.size();
vector<vector<bool>> dp(size, vector<bool>(size, false));
int left = 0; // 只需要获取字符串起始索引即可
int maxLen = 1;
for (int i = size - 1; i >= 0; i--)
for (int j = i; j < size; j++) {
if (s[i] != s[j]) continue;
// 三种情况合到一起([1] "a" [2] "aa" [3] "..bab..")
if (j - i <= 1 || dp[i + 1][j - 1])
dp[i][j] = true;
if (dp[i][j] && maxLen < j - i + 1) {
maxLen = j - i + 1;
left = i;
}
}
return s.substr(left, maxLen);
}
};
2 双指针(中心扩展)
class Solution {
public:
void extend(string& s, int c1, int c2, int& maxLen, int& left) {
int len = 0;
while (c1 >= 0 && c2 < s.size() && s[c1] == s[c2]) {
len = c2 - c1 + 1;
c1--; c2++;
}
if (len > maxLen) {
maxLen = len;
left = c1 + 1;
}
}
string longestPalindrome(string s) {
int left = 0, maxLen = 1;
for (int i = 0; i < s.size(); i++) {
extend(s, i, i, maxLen, left);
extend(s, i, i + 1, maxLen, left);
}
return s.substr(left, maxLen);
}
};