📜  计算所有素长度回文子串(1)

📅  最后修改于: 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)$,但这里不再赘述。