给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba"
同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
示例 3:
输入:s = "a"
输出:"a"
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成
解法:
(暴力枚举) O(n2)
由于字符串长度小于1000,因此我们可以用 O(n2) 的算法枚举所有可能的情况。
首先枚举回文串的中心 ii,然后分两种情况向两边扩展边界,直到遇到不同字符为止:
回文串长度是奇数,则依次判断 s[i−k]==s[i+k],k=1,2,3,…s[i−k]==s[i+k],k=1,2,3,…
回文串长度是偶数,则依次判断 s[i−k]==s[i+k−1],k=1,2,3,…s[i−k]==s[i+k−1],k=1,2,3,…
如果遇到不同字符,则我们就找到了以 ii 为中心的回文串边界。
时间复杂度分析:一共两重循环,所以时间复杂度是 O(n2)。
class Solution {
public:
string longestPalindrome(string s) {
int res = 0;
string str;
for (int i = 0 ; i < s.size(); i ++)
{
for (int j = 0; i - j >= 0 && i + j < s.size(); j ++)
{
if (s[i - j] == s[i + j])
{
if (j * 2 + 1 > res)
{
res = j * 2 + 1;
str = s.substr(i - j, j * 2 + 1);
// 更新最大长度, 并取出来这个字符串[i-j, j * 2 + 1];
}
} else break;
}
for (int j = i, k = i + 1; j >= 0 && k < s.size(); j -- , k ++)
{
// i, i + 1 偶数个数时,
if (s[j] == s[k])
{
if (k - j + 1 > res)
{
res = k - j + 1;
str = s.substr(j, k - j + 1);
// 更新最大长度 k - j + 1, 取出字符串 [j, k - j + 1]
}
} else break;
}
}
return str;
}
};