【LeetCode】5. 最长回文子串
以下是使用 中心扩展法 实现的最长回文子串解决方案,时间复杂度为 O(n²),空间复杂度为 O(1),适合处理中等规模的字符串:
func longestPalindrome(s string) string { if len(s) == 0 { return "" } start, end := 0, 0 for i := 0; i < len(s); i++ { // 处理奇数长度回文(如 "aba") l1, r1 := expand(s, i, i) // 处理偶数长度回文(如 "abba") l2, r2 := expand(s, i, i+1) // 更新最长回文边界 if r1 - l1 > end - start { start, end = l1, r1 } if r2 - l2 > end - start { start, end = l2, r2 } } return s[start:end+1] } // 从中心向两边扩展,返回回文的最左/右边界 func expand(s string, left, right int) (int, int) { for left >= 0 && right < len(s) && s[left] == s[right] { left-- right++ } // 回退到最后一个满足条件的边界 return left + 1, right - 1 }
算法说明
-
核心思想
遍历每个可能的回文中心(每个字符和每两个字符中间的位置),向两侧扩展检测回文。- 奇数长度回文:以单个字符为中心(如
"aba"以'b'为中心) - 偶数长度回文:以两个字符中间为中心(如
"abba"以中间两个'b'为中心)
- 奇数长度回文:以单个字符为中心(如
-
复杂度分析
- 时间复杂度:O(n²),遍历每个中心点 O(n),每个中心扩展 O(n)
- 空间复杂度:O(1),仅使用常数级额外空间
-
关键优化点
- 直接返回字符串切片
s[start:end+1],避免额外内存分配 - 统一处理奇偶两种回文类型,减少代码重复
- 直接返回字符串切片
测试示例
func main() { fmt.Println(longestPalindrome("babad")) // 输出 "bab" 或 "aba" fmt.Println(longestPalindrome("cbbd")) // 输出 "bb" fmt.Println(longestPalindrome("a")) // 输出 "a" }
扩展:Manacher 算法(O(n) 时间复杂度)
若需要处理超长字符串(例如长度超过 10^4),可使用 Manacher 算法。该算法通过预处理字符串和利用对称性减少重复计算,但实现较复杂:
func longestPalindromeManacher(s string) string { if len(s) < 2 { return s } // 预处理:插入特殊字符 '#' newS := make([]rune, 0) newS = append(newS, '#') for _, c := range s { newS = append(newS, c) newS = append(newS, '#') } // 计算每个位置的回文半径 dp := make([]int, len(newS)) maxRight, center, maxLen, begin := 0, 0, 1, 0 for i := 0; i < len(newS); i++ { if i < maxRight { dp[i] = min(maxRight-i, dp[2*center-i]) } left, right := i-(1+dp[i]), i+(1+dp[i]) for left >= 0 && right < len(newS) && newS[left] == newS[right] { dp[i]++ left-- right++ } if i+dp[i] > maxRight { maxRight = i + dp[i] center = i } if dp[i] > maxLen { maxLen = dp[i] begin = (i - maxLen) / 2 } } return s[begin : begin+maxLen] } func min(a, b int) int { if a < b { return a } return b }
方法对比
| 方法 | 时间复杂度 | 空间复杂度 | 适用场景 |
|---|---|---|---|
| 中心扩展法 | O(n²) | O(1) | 一般长度字符串 |
| Manacher算法 | O(n) | O(n) | 超长字符串(1e5+) |
可根据实际需求选择实现方式。中心扩展法更简洁,Manacher 算法适合高性能场景。

浙公网安备 33010602011771号