📌  相关文章
📜  每个字符出现偶数次的子串数(1)

📅  最后修改于: 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
总结

本题是一道比较巧妙的字符串问题,需要好好想一想。在解决这道题的过程中,我们需要运用异或的思想,同时也涉及到了前缀和的转化,可能会对算法的思考和编码能力有所提升。