📌  相关文章
📜  计算给定字符串的子字符串,其字谜是回文(1)

📅  最后修改于: 2023-12-03 15:28:04.459000             🧑  作者: Mango

计算给定字符串的子字符串,其字谜是回文

回文是指正反顺序读都相同的字符串,例如 "level" 和 "racecar"。现在我们的任务是在给定字符串中查找所有回文子字符串。

方法一:暴力枚举

首先,我们可以使用暴力枚举的方法来解决这个问题。我们可以枚举所有的子字符串,然后依次判断每个子字符串是否是回文。

def is_palindrome(s):
    return s == s[::-1]

def find_palindromic_substrings(s):
    res = []
    for i in range(len(s)):
        for j in range(i, len(s)):
            if is_palindrome(s[i:j+1]):
                res.append(s[i:j+1])
    return res

这个方法的时间复杂度是 $O(n^3)$,其中 $n$ 是字符串的长度。可以发现,枚举子串的时间复杂度是 $O(n^2)$,判断子串是否是回文的时间复杂度是 $O(n)$。

方法二:中心拓展法

我们注意到所有的回文子字符串都是以一个中心点为轴对称的。因此,我们可以以每一个字符为中心点,向两端拓展,并判断拓展出来的字符串是否是回文。需要注意,回文子串长度可能是单数或双数,因此我们需要以每个字符为中心点,同时考虑它和下一个字符的中心点。

def find_palindromic_substrings(s):
    res = []
    for i in range(len(s)):
        # 以 i 为中心点,向两端拓展
        l, r = i, i
        while l >= 0 and r < len(s) and s[l] == s[r]:
            res.append(s[l:r+1])
            l -= 1
            r += 1
        # 以 i 和 i+1 为中心点,向两端拓展
        l, r = i, i+1
        while l >= 0 and r < len(s) and s[l] == s[r]:
            res.append(s[l:r+1])
            l -= 1
            r += 1
    return res

这个方法的时间复杂度是 $O(n^2)$。

总结

中心拓展法是一种非常高效的查找回文子串的方法,其时间复杂度为 $O(n^2)$。相比之下,暴力枚举的时间复杂度为 $O(n^3)$,显然效率低下。在实际应用中,我们应当尽量避免使用暴力枚举,而采用更高效的算法。