1. 项目概述
作为一名长期奋战在算法竞赛一线的开发者,我深知回文串问题在各类编程比赛和实际工程中的重要性。最长回文子串问题看似简单,但想要高效解决却需要巧妙的算法设计。今天我要分享的Manacher算法(俗称"马拉车"算法),正是解决这类问题的利器。
这个算法由Glenn Manacher在1975年提出,能够在O(n)时间复杂度内找到字符串中的最长回文子串。相比朴素的中心扩展法,它的性能提升显著。我在多次算法竞赛中亲身体验过它的威力,特别是在处理大规模字符串时,效率差异尤为明显。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心概念解析
2.1 回文串基础定义
回文串是指正读反读都相同的字符串,比如"madam"、"racecar"。在算法处理中,我们需要明确几个关键概念:
- 奇回文串:长度为奇数的回文串,如"aba"
- 偶回文串:长度为偶数的回文串,如"abba"
- 回文中心:对于奇回文串就是中间字符位置;对于偶回文串则是中间两个字符之间的位置
- 回文半径:从回文中心到回文串一端(包含中心)的字符数
2.2 预处理技巧
为了统一处理奇偶回文串,Manacher算法采用了一个巧妙的预处理方法:在原始字符串的每个字符间和首尾插入特殊字符(通常用'#')。例如:
原始字符串:"abba"
预处理后:"#a#b#b#a#"
这种处理有两大优势:
- 将偶回文转换为奇回文,简化处理逻辑
- 保证预处理后的字符串长度总是奇数,避免边界条件处理
3. 中心扩展算法解析
3.1 基本思路
中心扩展法是理解Manacher算法的基础。其核心思想是:
- 遍历字符串的每个字符和字符间隙作为潜在的回文中心
- 从中心向两侧扩展,比较字符是否相同
- 记录能扩展到的最长回文半径
3.2 实现细节
cpp复制int expandAroundCenter(const string& s, int left, int right) {
while (left >= 0 && right < s.size() && s[left] == s[right]) {
left--;
right++;
}
return right - left - 1;
}
string longestPalindrome(string s) {
if (s.empty()) return "";
int start = 0, end = 0;
for (int i = 0; i < s.size(); i++) {
int len1 = expandAroundCenter(s, i, i); // 奇回文
int len2 = expandAroundCenter(s, i, i+1); // 偶回文
int len = m
