📅  最后修改于: 2023-12-03 15:26:53.367000             🧑  作者: Mango
给定一个字符串,求其中每个字符出现次数都是偶数的子串数量。
例如,字符串 abbba
,每个字符出现的次数都是偶数的子串有 a
, b
, bb
, abbba
,共计4个。
一种朴素的算法是暴力枚举所有子串,然后对每个子串判断其中每个字符出现次数是否都是偶数,时间复杂度为 $O(n^3)$,显然会超时。
更好的算法是基于异或的思想,假设 $x$ 是一个整数,$S[i]$ 表示从字符串的第一个字符到第 $i$ 个字符的异或和(即 $S[i] = s_1 \oplus s_2 \oplus \cdots \oplus s_i$,其中 $\oplus$ 表示异或运算),那么从第 $i$ 个字符到第 $j$ 个字符的子串中每个字符出现次数都是偶数,当且仅当 $S[i-1] \oplus S[j] = 0$。
为什么会这样呢?因为 $S[i-1]$ 是从字符串的第一个字符开始到第 $i-1$ 个字符的异或和,$S[j]$ 是从字符串的第一个字符开始到第 $j$ 个字符的异或和,这样相减得到的就是从第 $i$ 个字符到第 $j$ 个字符的异或和,如果这个异或和都为偶数,说明其中每个字符出现次数都是偶数。
于是,我们只需要遍历所有的 $S[i-1]$ 和 $S[j]$ 的异或和,然后统计有多少个是偶数即可。
时间复杂度为 $O(n^2)$,能够通过本题。
以下是python的实现:
class Solution:
def countSubstring(self, s: str) -> int:
count = 0
n = len(s)
xor = [0] * (n + 1)
for i in range(n):
xor[i+1] = xor[i] ^ ord(s[i])
for i in range(n):
for j in range(i+1, n+1):
if xor[i] ^ xor[j] == 0:
count += 1
return count
本题是一道比较巧妙的字符串问题,需要好好想一想。在解决这道题的过程中,我们需要运用异或的思想,同时也涉及到了前缀和的转化,可能会对算法的思考和编码能力有所提升。