当前位置:首页 > 力扣题解 > 力扣2588题解:异或前缀和与哈希表统计美丽子数组

力扣2588题解:异或前缀和与哈希表统计美丽子数组

2天前力扣题解53

截图未命名.jpg 力扣2588题解:异或前缀和与哈希表统计美丽子数组 异或 前缀和 哈希表 二进制 力扣题解 C++ 第1张

一、问题分析

这道题目要求我们统计数组中所有"美丽"子数组的数量。美丽子数组的定义是:通过特定的二进制位操作可以将子数组中的所有元素变为0。关键在于理解这些操作的本质:

  1. 每次操作选择两个数,在它们的相同二进制位都为1时,可以同时减去该位的值

  2. 这种操作实际上相当于对两个数进行异或操作

  3. 因此,美丽子数组的条件等价于子数组中所有元素的异或结果为0

二、解题思路

我们可以使用异或前缀和哈希表来高效解决这个问题:

  1. 计算前缀异或和数组

  2. 使用哈希表统计每个异或值出现的次数

  3. 当相同的异或值再次出现时,说明这两个位置之间的子数组异或和为0

  4. 累加所有满足条件的子数组数量

三、C++代码实现

class Solution {
public:
    long long beautifulSubarrays(vector<int>& nums) {
        unordered_map<int, int> prefix_xor_counts;
        prefix_xor_counts[0] = 1; // 初始前缀异或和为0出现1次
       
        int current_xor = 0;
        long long result = 0;
       
        for (int num : nums) {
            current_xor ^= num; // 计算当前前缀异或和
           
            // 如果之前出现过相同的异或值,说明中间子数组异或和为0
            result += prefix_xor_counts[current_xor];
           
            // 更新当前异或值的出现次数
            prefix_xor_counts[current_xor]++;
        }
       
        return result;
    }
};

这段代码使用异或前缀和与哈希表高效统计美丽子数组数量,时间复杂度O(n),空间复杂度O(n)。

四、代码详解

  1. 初始化哈希表‌:

    • 存储前缀异或和及其出现次数

    • 初始状态前缀异或和为0出现1次

  2. 遍历数组‌:

    • 计算当前前缀异或和

    • 如果哈希表中已有该异或值,说明中间子数组异或和为0

    • 更新哈希表中当前异或值的计数

  3. 结果计算‌:

    • 每次遇到重复的异或值,就增加相应数量的美丽子数组

    • 最终返回所有美丽子数组的总数

五、算法优化

  1. 异或性质利用‌:

    • 利用异或运算的可逆性和结合律

    • 子数组异或和可以通过前缀异或和差值计算

  2. 哈希表优化‌:

    • 使用unordered_map实现O(1)时间的查询和插入

    • 避免重复计算,直接累加已有结果

六、扩展思考

  1. 如果操作规则变化,比如可以同时对三个数进行操作,算法该如何调整?

  2. 如何修改算法来找出所有美丽子数组的具体位置而不仅仅是计数?

  3. 如果数组非常大,如何进一步优化空间复杂度?

掌握这种异或前缀和与哈希表的组合解法,能够帮助你解决许多类似的子数组统计问题!


原创内容 转载请注明出处

分享给朋友:

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。