def solution(S):
total = 0
i = 1
while i <= len(S):
for j in range(0, len(S) - i + 1):
if is_p(S[ j: j + i]):
total += 1
i += 1
return total
def is_p(S):
if len(S) == 1:
return False
elif S == S[::-1]:
return True
else:
return False
我正在编写一个函数来计算字符串中回文切片(长度大于1)的数量。上面的代码时间复杂度很低。有人可以帮助我改进它并使其具有O(N)复杂性吗?
编辑:这不是重复,因为另一个问题是关于寻找最长的回文切片
答案 0 :(得分:0)
这可以使用后缀树在线性时间内完成:
1)对于常量字母表,我们可以使用U(n)中的Ukkonen算法构建后缀树。
2)对于给定的字符串S,构建S#S'的通用后缀树,其中S'与字符串S相反,#是分隔字符。
3)现在在这个后缀树中,对于S中的每个后缀i,寻找(2n-i + 1)后缀的最低共同祖先是S'。
4)计算树中所有这些后缀的数量,以获得所有回文的总数。
答案 1 :(得分:0)
应用Manacher's Algorithm,同样由multiple answers to this question描述。
它为您提供以每个位置为中心的最长回文的长度(以奇数长度为中心,或以偶数长度为中心)。您可以使用它来轻松计算回文的数量。请注意,每个回文必须位于某处的中心位置,因此它必须是以中心为中心的最长回文的子串(或等于)。
因此请考虑字符串ababcdcbaa
。通过Manacher算法,您知道以d
为中心的最大长度回文长度为7:abcdcba
。根据回文的属性,您立即知道bcdcb
和cdc
以及d
也是以d
为中心的回文。事实上,如果你知道那里居中的最长回文的长度为floor((k+1)/2)
,那么k
回文就会集中在一个位置。
因此,您总结了Manacher算法的结果,以计算所有回文数。如果您只想计算长度为> 1
的回文,您只需要减去长度为1的回文数,这只是n
,即字符串的长度。