版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_17677907/article/details/88086795
985. 查询后的偶数和
题目描述
给出一个整数数组 A 和一个查询数组 queries。
对于第 i 次查询,有 val = queries[i][0], index = queries[i][1],我们会把 val 加到 A[index] 上。然后,第 i 次查询的答案是 A 中偶数值的和。
返回所有查询的答案
方法一 暴力
思路与算法
先执行更新数组操作,然后对偶数求和,串行。问题在于复杂度太高,超时
def sumEvenAfterQueries(A:'List[int]', queries: 'List[List[int]]') -> 'List[int]':
ans = []
for query in queries:
# 更新数组
A[query[1]] += query[0]
# 计算偶数和
sum = sum(i for i in A if x % 2 == 0)
ans.append(sum)
return ans
复杂度分析
- 时间复杂度 O(N*) N是数组A的长度 Q是询问queries的数量
方法二 剪枝
思路
可以对方法一中的部分情况进行判断,减少计算的次数
算法
利用奇偶相加还是奇数的原理进行剪枝在,只需要对当前修改位置元素的奇偶进行判断,其余位置的元素不会产生影响
def sumEvenAfterQueries3(A:'List[int]', queries: 'List[List[int]]') -> 'List[int]':
ans = []
# 首先计算原始序列中的偶数和
ret = sum(x for x in A if x % 2 == 0)
for val, pos in queries: # 这里使用的是解包的技巧
if A[pos] % 2 == 0: # 如果修改位置是偶数,加上偶数还是偶数,总结果中加上。加上奇数变成奇数,总结果中减去
if val % 2 == 0:
ret += val
else:
ret -= A[pos]
else: # 如果修改位置是奇数,只有加上奇数的情况上才在总结果中加上
if val % 2:
ret += val + A[pos]
A[pos] += val
ans.append(ret)
return ans
c++
vector<int> sumEvenAfterQueries(vector<int>& A, vector<vector<int>>& queries) {
vector<int> vi;
int ou = 0;
for (int i = 0; i < A.size(); i++) {//计算所有偶数和
if (A[i] % 2 == 0) {
ou += A[i];
}
}
for (int i = 0; i < queries.size(); i++) {
if (A[queries[i][1]] % 2 == 0) {//查询的为偶数
ou -= A[queries[i][1]];
if (queries[i][0] % 2 == 0) {//要加的为偶数
A[queries[i][1]] += queries[i][0];
ou += A[queries[i][1]];
}
else {
A[queries[i][1]] += queries[i][0];
}
}
else {
if (queries[i][0] % 2 != 0) {
A[queries[i][1]] += queries[i][0];
ou += A[queries[i][1]];
}
else {
A[queries[i][1]] += queries[i][0];
}
}
vi.push_back(ou);
}
return vi;
}
复杂度分析
- 时间复杂度 O(N + Q) N是数组A的长度,Q是询问queries的数量
方法三 剪枝二
思路与算法
不同的剪枝策略
- 如果当前项是偶数,计算出其余的偶数和。如果是奇数,整体的偶数和就是其余项的偶数和。
- 然后对当前项进行修改
- 修改后为偶数 则加到其余项的偶数和中去
python
def sumEvenAfterQueries4(A:'List[int]', queries: 'List[List[int]]') -> 'List[int]':
ans = []
ret = sum(x for x in A if x % 2 == 0)
for val, pos in queries:
# 第一步 计算出其余未修改项中的偶数和
if A[pos] % 2 == 0:
ret -= A[pos]
# 第二步 进行更新
A[pos] += val
# 第三步 判断更新后的值
if A[pos] % 2 == 0:
ret += A[pos]
ans.append(ret)
return ans
复杂度分析
- 时间复杂度 O(N + Q) N是数组A的长度,Q是询问queries的数量
- 空间复杂度:O(N+Q)O(N+Q),事实上我们只使用了 O(1)O(1) 的额外空间。