【前缀和】LeetCode - 1310. 子数组异或查询

本文介绍了如何运用前缀和与异或的性质优化算法,以解决二维数组查询的问题。通过预先计算数组的前缀异或和,可以将时间复杂度从平方级别降低到线性级别,从而提高效率。文章提供了两种不同的实现方式,并推荐了更节省空间和时间的第二种写法。这种方法展示了在算法设计中如何通过空间换时间来提升性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

题目链接
在这里插入图片描述在这里插入图片描述

解法

前缀和

  • 即一个数组中,第 n 位存储的是数组前 n 个数字的和。
  • 对 [1,2,3,4,5,6] 来说,其前缀和可以是 pre=[1,3,6,10,15,21]。我们可以使用公式 pre[𝑖]=pre[𝑖−1]+nums[𝑖] 得到每一位前缀和的值,从而通过前缀和进行相应的计算和解题。
  • 前缀和一般用在求 [i,j] 这样的二元问题上,可以转化为求 [0, j] - [0, i-1] ,就变成了 [0, x] 的一元问题

前缀和在本题的应用

  • 首先很容易想到双重循环,遍历查询数组挨个求值,时间复杂度是 O(n^2),空间复杂度是 O(1)

  • 那可不可以另辟一个空间 pre (数组或者Map或者其他你熟悉的),先把结果求好存下来,遍历的时候直接引用,就少了很多重复计算,这种思想即是前缀和的思想。

  • 本题其实还用到了异或的一个性质 x ^ y ^ x = y
    在这里插入图片描述

  • 这样的时间复杂度是 O(n),空间复杂度是 O(n),典型的用空间换取时间,但显然这种换取是有价值的

  • 分析本题,因为只在计算前缀和时用到了arr,后续算法与它无关,所以我们可以直接在arr上修改

class Solution {
public:
    vector<int> xorQueries(vector<int>& arr, vector<vector<int>>& queries) {
        for(int i = 1; i < arr.size(); i++)
         arr[i] ^= arr[i-1];// ^= 是异或
        vector<int> ans;
        /****第一种写法****/
        for(vector<int> tmp : queries)
        {
            if(tmp[0] == 0)
             ans.push_back(arr[tmp[1]]);
            else
             ans.push_back(arr[tmp[0] - 1] ^ arr[tmp[1]]);
        }
        return ans;
    }
};
class Solution {
public:
    vector<int> xorQueries(vector<int>& arr, vector<vector<int>>& queries) {
        for(int i = 1; i < arr.size(); i++)
         arr[i] ^= arr[i-1];// ^= 是异或
        vector<int> ans;
        /****第二种写法****/
        for(int i = 0; i < queries.size(); i++)
        {
            if(queries[i][0] == 0)
             ans.push_back(arr[queries[i][1]]);
            else
             ans.push_back(arr[queries[i][0] - 1] ^ arr[queries[i][1]]);
        }
        return ans;
    }
};

推荐第二种写法,少占空间,少费时间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值