题目描述
解法
前缀和
- 即一个数组中,第 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;
}
};
推荐第二种写法,少占空间,少费时间