马拉车
马拉车只能处理连续回文
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
// 标准马拉车:只找一个最长回文子串
string findLongestPalindromicSubstring(string s) {
if (s.empty()) return "";
string t = "#";
for (char c : s) {
t += c;
t += '#';
}
int n = t.length();
vector<int> p(n, 0);
int center = 0, right = 0;
int maxCenter = 0, maxLen = 0;
for (int i = 0; i < n; i++) {
if (i < right) {
p[i] = min(right - i, p[2 * center - i]);
}
while (i - p[i] - 1 >= 0 && i + p[i] + 1 < n &&
t[i - p[i] - 1] == t[i + p[i] + 1]) {
p[i]++;
}
if (i + p[i] > right) {
center = i;
right = i + p[i];
}
// 关键:记录最长回文的中心位置
if (p[i] > maxLen) {
maxLen = p[i];
maxCenter = i;
}
}
int start = (maxCenter - maxLen) / 2;
return s.substr(start, maxLen);
}
int main() {
vector<string> testCases = {
"babad",
"cbbd",
"a",
"abc",
"aaa",
"abacaba"
};
for (string s : testCases) {
string result = findLongestPalindromicSubstring(s);
cout << "字符串: \"" << s << "\"" << endl;
cout << "最长回文子串: \"" << result << "\"" << endl;
cout << "长度: " << result.length() << endl;
cout << "------------------------" << endl;
}
return 0;
}
马拉车储存所有回文子串
vector<string> findAllLongestPalindromicSubstringsV2(string s) {
if (s.empty()) return {""};
// 预处理
string t = "#";
for (char c : s) {
t += c;
t += '#';
}
int n = t.length();
vector<int> p(n, 0);
int center = 0, right = 0;
int maxLen = 0;
// 第一步:执行标准马拉车算法
for (int i = 0; i < n; i++) {
if (i < right) {
p[i] = min(right - i, p[2 * center - i]);
}
while (i - p[i] - 1 >= 0 && i + p[i] + 1 < n &&
t[i - p[i] - 1] == t[i + p[i] + 1]) {
p[i]++;
}
if (i + p[i] > right) {
center = i;
right = i + p[i];
}
maxLen = max(maxLen, p[i]);
}
// 第二步:收集所有最长回文子串
vector<string> result;
for (int i = 0; i < n; i++) {
if (p[i] == maxLen) {
int start = (i - p[i]) / 2;
string palindrome = s.substr(start, maxLen);
// 去重
if (find(result.begin(), result.end(), palindrome) == result.end()) {
result.push_back(palindrome);
}
}
}
return result;
}

浙公网安备 33010602011771号