最长回文子串
问题
给你一个字符串 s,找到 s 中最长的回文子串(是字符串中连续的非空字符序列)。
方案一:暴力枚举法
思路:从最长可能子串开始,逐层缩短长度,检查是否回文,第一个找到最长回文子串。
时间复杂度:O(n³)
#include <string>
#include <algorithm>
using namespace std;
class Solution {
public:
string longestPalindrome(string s) {
// 不能用int length = strlen(s); strlen(s)只能用于 char* ,string用.size() 或 .length()
int length=s.size();
for(int len=length;len>0;len--){
for(int start=0;start+len<=length;start++){
// c++没有s[start,start+len]的切片语法
string sub=s.substr(start,len);
// reverse的返回值是void,函数将字符串原地翻转,而不是返回翻转的值
string rev=sub;
reverse(rev.begin(),rev.end());
// strcmp用于char*的比较,string使用==做字符串比较
if (sub==rev){
return sub;
}
}
}
return "";
}
};
方案二:中心扩展法
思路:依次遍历字符串的每个字符,假定该字符为回文子串的中心(奇数情况),依次判断其左右字符是否相同并填充字符子串;考虑回文子串中心为两个相同字符的情况(偶数情况)。同时记录最长子串的开始位置和长度。
时间复杂度O(n²)
class Solution {
public:
string longestPalindrome(string s) {
if (s.empty()) return "";
int start = 0, maxLen = 1;
for (int i = 0; i < s.size(); i++) {
// 奇数长度回文:中心是 s[i]
expandAroundCenter(s, i, i, start, maxLen);
// 偶数长度回文:中心是 s[i] 和 s[i+1]
expandAroundCenter(s, i, i + 1, start, maxLen);
}
return s.substr(start, maxLen);
}
private:
void expandAroundCenter(const string& s, int left, int right, int& start, int& maxLen) {
// 从中心向外扩展
while (left >= 0 && right < s.size() && s[left] == s[right]) {
int curLen = right - left + 1;
if (curLen > maxLen) {
maxLen = curLen;
start = left;
}
left--;
right++;
}
}
};
浙公网安备 33010602011771号