LeetCode 647:回文子串(Palindromic Substrings)—— 题解 ✅
🔗 题目链接
👉 https://leetcode.cn/problems/palindromic-substrings/
📖 内容概要
给定一个字符串 s,统计并返回 这个字符串中回文子串的数目。
子串是连续的,回文指正读和反读相同。
✅ 区间 DP
✅ 中心扩展思想的 DP 实现
✅ 面试高频题
💡 解题思路(核心)
一、状态定义
dp[i][j] = s[i...j] 是否是回文子串
二、状态转移方程(最重要)
if (s[i] == s[j]) {
if (j – i <= 1) {
dp[i][j] = true; // "a" 或 "aa"
} else {
dp[i][j] = dp[i+1][j–1]; // 依赖内部
}
}
✅ 外层字符相等
✅ 内部仍是回文
✅ 整体才是回文
三、遍历顺序(关键)
因为 dp[i][j] 依赖 dp[i+1][j-1]:
| i | 从大到小 |
| j | 从小到大 |
for (int i = len – 1; i >= 0; i—)
for (int j = i; j < len; j++)
✅ 保证子问题先计算完成
✅ AC 代码(Java,基于你的代码)
class Solution {
public int countSubstrings(String s) {
int res = 0;
char[] ss = s.toCharArray();
int len = s.length();
boolean[][] dp = new boolean[len][len];
for (int i = len – 1; i >= 0; i—) {
for (int j = i; j < len; j++) {
if (ss[i] == ss[j]) {
if (j – i <= 1) {
dp[i][j] = true;
res++;
} else if (dp[i + 1][j – 1]) {
dp[i][j] = true;
res++;
}
}
}
}
return res;
}
}
⏱️ 复杂度分析
| 时间复杂度 | O(n²) |
| 空间复杂度 | O(n²) |
🔍 与其他解法的对比
| 中心扩展 | O(n²) | O(1) | 面试最爱 |
| DP(本题) | O(n²) | O(n²) | 易理解 |
| Manacher | O(n) | O(n) | 偏竞赛 |
✅ 一句话总结
区间 DP:两端相等且内部是回文,则整体是回文。
📌 面试加分点(建议记住)
- ✅ 为什么 i 要从大到小?
- ✅ 为什么 j – i <= 1 要单独判断?
- ✅ DP 与中心扩展的本质联系
- ✅ 如何优化到 O(1) 空间?
![【题解】[COCI 2025/2026 #6] 滑雪 / Skijanje(李超树 0 基础友好喵)-171主机测评](https://www.171host.com/wp-content/uploads/2026/08/20260826083930-6a8ea642697bc-220x25.png)


