题目
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
示例 3:
输入:s = "a"
输出:"a"
示例 4:
输入:s = "ac"
输出:"a"
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
遍历数组,在每一个下标为 i
的地方,以 s[i]
为回文串的中心,或者以 s[i + 1]
为回文字符串的中心,寻找最长的回文串,然后记录下遍历过程中最长的回文串。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
a
n
s
.
s
i
z
e
(
)
)
O(ans.size())
O(ans.size())
C++ 代码 1
自己写的,代码比较复杂
class Solution {
public:
string longestPalindrome(string s) {
if (s.empty())
return string();
string ans;
for (int i = 0; i < s.size(); ++i) {
string palindrome = longestPalindromeCore(s, i);
if (palindrome.size() > ans.size())
ans = palindrome;
}
return ans;
}
string longestPalindromeCore(const string s, const int index) {
int halfOddLen = 0;
int halfEvenLen = 0;
while (index - halfOddLen >= 0 && index + halfOddLen < s.size()
&& s[index - halfOddLen] == s[index + halfOddLen]) {
++halfOddLen;
}
--halfOddLen;
while (index - halfEvenLen + 1 >= 0 && index + halfEvenLen < s.size()
&& s[index - halfEvenLen + 1] == s[index + halfEvenLen]) {
++halfEvenLen;
}
--halfEvenLen;
if (halfOddLen * 2 + 1 > halfEvenLen * 2)
return s.substr(index - halfOddLen, halfOddLen * 2 + 1);
else
return s.substr(index - halfEvenLen + 1, halfEvenLen * 2);
}
};
C++ 代码 2
思路和上面还是一样的,但是官方题解中的代码更加简单,看懂之后重新写了一遍(提交的时候执行用时还增加了):
class Solution {
public:
string longestPalindrome(string s) {
if (s.size() < 2)
return s;
string ans;
for (int i = 0; i < s.size() - 1; ++i) {
string palindrome = longestPalindromeCore(s, i, i);
if (palindrome.size() > ans.size())
ans = palindrome;
palindrome = longestPalindromeCore(s, i, i + 1);
if (palindrome.size() > ans.size())
ans = palindrome;
}
return ans;
}
string longestPalindromeCore(const string s, int lo, int hi) {
if (s[lo] != s[hi])
return string();
while (lo - 1 >= 0 && hi + 1 < s.size() && s[lo - 1] == s[hi + 1]) {
--lo;
++hi;
}
return s.substr(lo, hi - lo + 1);
}
};