BM73 最长回文子串¶
中等通过率 35.19%python3核心代码模式样例通过牛客 AC字符串动态规划
讲解章节:回文
一句话
枚举回文中心向两边扩张,取最长的一次扩张长度。
解题思路¶
这题考什么¶
回文串的定义性质是「关于中心对称」,这条性质直接给出一个降维的枚举方式: 不枚举左右端点(O(n^2) 对),只枚举中心(O(n) 个),再从中心往外扩到扩不动为止。 回文的系统讨论见 回文。
中心分两类,一共 2n-1 个:
扩张就是一个循环:
退出时 l、r 各自已经多走了一格(越界或字符不等), 所以真正的回文区间是 [l+1, r-1],长度 r - l - 1。取所有中心的最大值即答案。
也可以写成区间 DP:dp[i][j] 表示 A[i..j] 是否回文,
时间同为 O(n^2),但要开一张 n*n 的表,空间 O(n^2),还多出二维列表的寻址开销; 中心扩张只用两个下标,空间 O(1),正好命中题面要求。 真要做到 O(n) 还有 Manacher 算法,本题 n <= 1000 用不上它的复杂度优势。
数据规模与复杂度¶
1 <= n <= 1000,时限 2 秒(其他语言)。 2n-1 个中心,每个至多扩 n/2 步,最坏 O(n^2) = 1e6 次字符比较—— 最坏数据正是「全同字符」串,每个中心都能扩到底。 空间 O(1),只用 l、r、best 三个整数。
坑在哪¶
- 偶数长度的中心不能漏。只枚举单字符中心时 "abba" 会被答成 1, 因为它的对称轴落在两个 'b' 之间,不在任何字符上。
- 长度公式是 r - l - 1,不是 r - l + 1。循环退出时 l、r 已经各自越过边界一格, 少减这个 2 会把每个答案都放大 2。
- 奇数中心从 (c-1, c+1) 起手而不是 (c, c):单个字符自己必然回文, 没必要拿 A[c] 和自己比一次;起始长度 r - l - 1 已经等于 1。
- best 初值取 1 而不是 0:n >= 1 时任何单个字符都是长度 1 的回文。 n < 2 时直接返回 n,同时覆盖了 n = 0 与 n = 1。
- 扩张的越界判断必须写在字符比较之前,靠 Python 的短路求值挡住 A[-1]—— 负下标不会报错,只会悄悄绕到串尾,把不相邻的字符判成对称。
样例复核¶
"ababc":c = 1 的奇数中心扩出 "aba"(l = -1、r = 3,长度 3), c = 2 的奇数中心扩出 "bab",其余中心都不超过 3,答案 3,与期望输出一致。
参考实现¶
[:octicons-arrow-left-16: BM72](BM72.md) [BM74 :octicons-arrow-right-16:](BM74.md)