算法 - 最长回文子串(中心扩散法)
1. 题目
给你一个字符串 s,找到其中最长的回文子串。回文指正读反读都一样。
示例:
1 | 输入: s = "babad" |
2. 解题思路
2.1 中心扩散(推荐,直观且高效)
回文串一定围绕某个「中心」对称展开。长度为 n 的字符串共有 2n - 1 个中心:
n个单字符中心(产生奇数长度回文,如 “aba”)。n - 1个双字符间隙中心(产生偶数长度回文,如 “abba”)。
枚举每个中心,向两边同时扩展直到不再相等,记录最长的一段。每个中心调用一次扩散函数,分别以 i(奇)和 i, i+1(偶)为初始左右指针。
- 时间复杂度:
O(n²);空间复杂度:O(1)。
2.2 动态规划 O(n²) 空间
dp[i][j] 表示 s[i..j] 是否回文:dp[i][j] = (s[i]===s[j]) && dp[i+1][j-1]。按长度从小到大填表。空间更大,思路清晰可作为对照。
存在
O(n)的 Manacher 算法,面试一般不要求手写,能提名字并说明它是「利用已知回文的对称性避免重复扩展」即为加分。
3. TypeScript 实现
1 | function longestPalindrome(s: string): string { |
4. 面试延伸
- 起点公式
i - (len-1)/2是易错点:奇偶都适用,因为(len-1)/2向下取整正好覆盖两种中心的偏移差异。 - 最长回文子序列(516):子序列可不连续,转成「s 与 reverse(s) 的 LCS」或区间 DP
dp[i][j],别和本题混淆。 - Manacher:把 O(n²) 优化到 O(n),核心是维护「右边界最大的回文」及其对称中心,复用已知信息。
- 字符串匹配类(回文、子串、子序列)先问自己:中心?双指针?区间 DP?——建立这三选一的直觉。
难度:中等 | LeetCode 5 题 | 中心扩散模板