📅  最后修改于: 2023-12-03 15:28:01.910000             🧑  作者: Mango
回文子串指的是正反读都相同的字符串。素长度的回文子串指的是由素数个字符组成的回文子串。本篇介绍如何计算一个字符串中所有素长度回文子串的个数。
一种简单的算法是枚举每个可能的回文子串,检查其是否由素数个字符组成。但这样的时间复杂度为 $O(n^3)$,无法通过本题。
我们可以换一种思路,从中心想象每一个回文子串,计算它对结果的贡献。对于每个中心,我们向左向右扩展,直到无法构成回文串,找到能够构成素长回文子串的数量。
假设有 $n$ 个字符,那么一共有 $2n-1$ 个可能的中心,因为一个回文子串可能位于两个字符之间。同时,由于一个偶数长度的回文串有两个中心,所以类似 “bb” 的字符串其回文中心为 "b"。
因此我们需要枚举每个可能的中心,计算它对结果的贡献。
def count_palindromic_substrings(s: str) -> int:
def is_prime(n: int) -> bool:
if n <= 1:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
def count_palindromic_substrings_from_center(l: int, r: int) -> int:
count = 0
while l >= 0 and r < len(s) and s[l] == s[r]:
if is_prime(r - l + 1):
count += 1
l -= 1
r += 1
return count
count = 0
for i in range(len(s)):
count += count_palindromic_substrings_from_center(i, i)
count += count_palindromic_substrings_from_center(i, i + 1)
return count
本算法的时间复杂度为 $O(n^2 log n)$,其中 $O(log n)$ 的时间用于判断是否为素数。同时,我们可以使用 Manacher 算法,将时间复杂度优化到 $O(n)$,但这里不再赘述。