📅  最后修改于: 2023-12-03 15:40:39.572000             🧑  作者: Mango
在字符串中找出所有满足每个字符出现次数均为偶数的子串数目。
例如,在字符串 "abcab" 中,满足条件的子串有 "a", "b", "c", "ab", "bc" 和 "cab" 共 $6$ 个。
本题可以使用简单的数学方法来解决,即计算每个子串中每个字符出现的次数,并判断是否均为偶数。
具体来说,可以使用一个长度为 $n$ 的整数数组 $count$ 记录每个字符在子串中出现的次数。遍历所有子串并计算字符出现次数的复杂度为 $O(n^2)$,而判断是否为偶数则只需要遍历一次 $count$ 数组,复杂度为 $O(k)$($k$ 为字符集大小,本题中 $k=26$)。因此总时间复杂度为 $O(n^2k)$。
另一种解法是将问题转化为异或和的形式。对于一个子串 $[l,r]$,定义 $s_i$ 为从左往右第 $i$ 个字符在子串中出现的次数的奇偶性($s_i=0$ 表示出现偶数次,$s_i=1$ 表示出现奇数次)。那么子串中每个字符出现次数均为偶数的充要条件是所有 $s_i$ 的异或和为 $0$。因此可以遍历所有子串并计算其异或和,用哈希表记录每个异或和出现的次数即可。时间复杂度为 $O(nk)$。
以下是第二种解法的代码(Python 3 实现):
def countSubstrings(s: str) -> int:
n = len(s)
count = defaultdict(int)
count[0] = 1 # 空串的异或和为 0
res, xor = 0, 0
for i in range(n):
xor ^= 1 << (ord(s[i]) - ord('a'))
res += count[xor]
for j in range(26):
res += count[xor ^ (1 << j)]
count[xor] += 1
return res
其中 xor
记录当前子串的异或和,count
为哈希表,记录每个异或和出现的次数。由于 Python 中默认的哈希表(dict
)不支持默认值,因此使用了 defaultdict
。