@Aryami
题目
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
示例 3:
输入:s = “a”
输出:“a”
示例 4:
输入:s = “ac”
输出:“a”
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成
题解
- 动态规划
dp[left][right]表示从 l e f t left left到 r i g h t right right是回文串。回文串长度为0,dp为真;回文串长度为1,保证 l e f t left left= r i g h t right right,dp为真;回文串长度大于1,dp[left+1][right-1]为真且 l e f t left left= r i g h t right right,dp为真。时间复杂度为 O ( n 2 ) O(n^2) O(n2),空间复杂度为 O ( n 2 ) O(n^2) O(n2)。
class Solution {
public:
string longestPalindrome(string s) {
int n = s.size();
if(n<2)
return s;
string res;
vector<vector<int>> dp(n, vector<int>(n));
for(int L=0; L<n; L++)
{
for(int left=0; left+L<n; left++)
{
int right = L + left;
if(L==0)
dp[left][right] = 1;
else if(L==1)
dp[left][right] = (s[left]==s[right]);
else
dp[left][right] = (dp[left+1][right-1] && s[left]==s[right]);
if(dp[left][right] && (L+1)>res.size())
res = s.substr(left, L+1);
}
}
return res;
}
};
- 中心扩展
子串为回文串的两种可能分别为有中心点和无中心点。对每个点遍历,扩展这两种情况,保留最大回文串长度。时间复杂度为 O ( n 2 ) O(n^2) O(n2),空间复杂度为 O ( 1 ) O(1) O(1)。
class Solution {
public:
int left=0, right=0;
int length=0;
string longestPalindrome(string s) {
for(int i=0; i<s.size(); i++)
{
extend(s, i, i, s.size());
extend(s, i, i+1, s.size());
}
return s.substr(left, length);
}
void extend(string &s, int i, int j, int n)
{
while(i>=0 && j<n && s[i]==s[j])
{
if(j-i+1>length)
{
left = i;
right = j;
length = right - left + 1;
}
i--;
j++;
}
}
};