想系统提升编程能力、查看更完整的学习路线,欢迎访问 AI Compass:github.com/tingaicompa… 仓库持续更新刷题题解、Python 基础和 AI 实战内容,适合想高效进阶的你。
📖 第20课:回文子串
模块:字符串 | 难度:Medium ⭐⭐ LeetCode 链接:leetcode.cn/problems/pa… 前置知识:第18课(最长回文子串)、中心扩展法 预计学习时间:25分钟
🎯 题目描述
给你一个字符串 s,请你统计并返回这个字符串中回文子串的数目。
回文字符串是正着读和倒着读都一样的字符串。
子字符串是字符串中连续的字符序列。
示例1:
输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"
示例2:
输入:s = "aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
约束条件:
1 <= s.length <= 1000s由小写英文字母组成
🧪 边界用例(面试必考)
| 用例类型 | 输入 | 期望输出 | 考察点 |
|---|---|---|---|
| 单字符 | s = "a" | 1 | 最小输入,单字符是回文 |
| 无长回文 | s = "abc" | 3 | 只有单字符回文 |
| 全相同 | s = "aaa" | 6 | "a"×3 + "aa"×2 + "aaa"×1 = 6 |
| 奇数回文 | s = "aba" | 4 | "a", "b", "a", "aba" |
| 偶数回文 | s = "abba" | 6 | "a", "b", "b", "a", "bb", "abba" |
💡 思路引导
生活化比喻
想象你在一本书里找"回文句子",不是要找最长的那句,而是要数出一共有多少句...
🐌 笨办法:枚举所有可能的子串,逐个检查是否为回文,每找到一个就计数+1。效率极低。
🚀 聪明办法:从每个可能的"中心点"出发,向两边扩展,每扩展成功一次,计数就+1。
关键洞察
本题和第18课的区别:第18课求"最长",本题求"数量"。核心方法相同——中心扩展法!
🧠 解题思维链
Step 1:理解题目 → 锁定输入输出
- 输入:字符串
s,长度 1 ~ 1000 - 输出:回文子串的总数量(整数)
Step 2:先想笨办法(暴力法)
枚举所有子串(起点i,终点j),逐个检查是否回文,是的话计数+1。
- 时间复杂度:O(n³)
Step 3:瓶颈分析 → 优化方向
回文的关键特征:中心对称!
- 优化思路:从每个中心出发,向两边扩展,每扩展成功一次就是一个回文
Step 4:选择武器
- 选用:中心扩展法
- 时间复杂度降到 O(n²)
🔑 解法一:中心扩展法(推荐⭐⭐⭐)
Python代码
def count_substrings(s: str) -> int:
"""
解法一:中心扩展法
思路:从每个中心向两边扩展,每扩展成功一次计数+1
"""
def expand_around_center(left: int, right: int) -> int:
"""从中心(left, right)向两边扩展,返回回文数量"""
count = 0
while left >= 0 and right < len(s) and s[left] == s[right]:
count += 1
left -= 1
right += 1
return count
total = 0
for i in range(len(s)):
# 奇数长度回文
total += expand_around_center(i, i)
# 偶数长度回文
total += expand_around_center(i, i + 1)
return total
# ✅ 测试
print(count_substrings("abc")) # 3
print(count_substrings("aaa")) # 6
复杂度分析
- 时间复杂度:O(n²)
- 空间复杂度:O(1)
📊 解法对比
推荐使用中心扩展法(时空最优,O(n²) 时间,O(1) 空间)
🎤 面试现场
你:这道题和"最长回文子串"类似,都用中心扩展法,但目标不同——之前求最长,现在求数量。
从每个中心出发向两边扩展,每扩展成功一次(左右字符相同)就找到一个回文,计数+1。
时间 O(n²),空间 O(1)。
🎓 知识点总结
算法模式卡片 📐
def count_palindromes(s: str) -> int:
"""中心扩展计数模板"""
def expand(left, right):
count = 0
while left >= 0 and right < len(s) and s[left] == s[right]:
count += 1
left -= 1
right += 1
return count
total = 0
for i in range(len(s)):
total += expand(i, i) # 奇数回文
total += expand(i, i + 1) # 偶数回文
return total
🏋️ 举一反三
| 题目 | 难度 | 提示 |
|---|---|---|
| LeetCode 5. 最长回文子串 | Medium | 本题的姊妹题,求最长而非数量 |
| LeetCode 516. 最长回文子序列 | Medium | 子序列可以不连续,需要DP |
💪 继续加油!
如果这篇内容对你有帮助,推荐收藏 AI Compass:github.com/tingaicompa… 更多系统化题解、编程基础和 AI 学习资料都在这里,后续复习和拓展会更省时间。