Medium
题目描述
给你一个整数数组 nums 和一个查询数组 queries,其中 queries[i] = [val_i, index_i]。
对于每个查询 i,首先,向 nums[index_i] 添加 val_i,即执行 nums[index_i] = nums[index_i] + val_i,然后打印 nums 中偶数值的和。
返回一个整数数组 answer,其中 answer[i] 是第 i 个查询的答案。
示例 1:
输入:nums = [1,2,3,4], queries = [[1,0],[-3,1],[-4,0],[2,3]]
输出:[8,6,2,4]
解释:开始时,数组为 [1,2,3,4]。
将 1 加到 nums[0] 上之后,数组为 [2,2,3,4],偶数值之和为 2 + 2 + 4 = 8。
将 -3 加到 nums[1] 上之后,数组为 [2,-1,3,4],偶数值之和为 2 + 4 = 6。
将 -4 加到 nums[0] 上之后,数组为 [-2,-1,3,4],偶数值之和为 -2 + 4 = 2。
将 2 加到 nums[3] 上之后,数组为 [-2,-1,3,6],偶数值之和为 -2 + 6 = 4。
示例 2:
输入:nums = [1], queries = [[4,0]]
输出:[0]
提示:
1 <= nums.length <= 10^4-10^4 <= nums[i] <= 10^41 <= queries.length <= 10^4-10^4 <= val_i <= 10^40 <= index_i < nums.length
解题思路
这道题目要求我们在每次查询后计算数组中偶数的和。我们可以采用两种方法来解决:
方法一:朴素解法 对于每个查询,更新对应位置的值,然后重新计算整个数组中偶数的和。这种方法简单直接,但时间复杂度较高。
方法二:优化解法(推荐) 我们可以先计算初始数组中所有偶数的和,然后对于每个查询操作,只需要根据更新前后的值来调整这个偶数和。具体步骤如下:
- 预先计算数组中所有偶数的和
- 对于每个查询
[val, index]:- 记录当前
nums[index]的值为old_val - 如果
old_val是偶数,从总和中减去它 - 更新
nums[index] += val,得到新值new_val - 如果
new_val是偶数,将其加到总和中 - 将当前的偶数和加入结果数组
- 记录当前
这种方法避免了每次查询都要重新计算整个数组的和,大大提升了效率。
代码实现
class Solution {
public:
vector<int> sumEvenAfterQueries(vector<int>& nums, vector<vector<int>>& queries) {
int evenSum = 0;
for (int num : nums) {
if (num % 2 == 0) {
evenSum += num;
}
}
vector<int> result;
for (auto& query : queries) {
int val = query[0];
int index = query[1];
int oldVal = nums[index];
if (oldVal % 2 == 0) {
evenSum -= oldVal;
}
nums[index] += val;
int newVal = nums[index];
if (newVal % 2 == 0) {
evenSum += newVal;
}
result.push_back(evenSum);
}
return result;
}
};
class Solution:
def sumEvenAfterQueries(self, nums: List[int], queries: List[List[int]]) -> List[int]:
even_sum = sum(num for num in nums if num % 2 == 0)
result = []
for val, index in queries:
old_val = nums[index]
if old_val % 2 == 0:
even_sum -= old_val
nums[index] += val
new_val = nums[index]
if new_val % 2 == 0:
even_sum += new_val
result.append(even_sum)
return result
public class Solution {
public int[] SumEvenAfterQueries(int[] nums, int[][] queries) {
int evenSum = 0;
foreach (int num in nums) {
if (num % 2 == 0) {
evenSum += num;
}
}
int[] result = new int[queries.Length];
for (int i = 0; i < queries.Length; i++) {
int val = queries[i][0];
int index = queries[i][1];
int oldVal = nums[index];
if (oldVal % 2 == 0) {
evenSum -= oldVal;
}
nums[index] += val;
int newVal = nums[index];
if (newVal % 2 == 0) {
evenSum += newVal;
}
result[i] = evenSum;
}
return result;
}
}
var sumEvenAfterQueries = function(nums, queries) {
let evenSum = nums.reduce((sum, num) => num % 2 === 0 ? sum + num : sum, 0);
let result = [];
for (let [val, index] of queries) {
let oldVal = nums[index];
let newVal = oldVal + val;
if (oldVal % 2 === 0) {
evenSum -= oldVal;
}
nums[index] = newVal;
if (newVal % 2 === 0) {
evenSum += newVal;
}
result.push(evenSum);
}
return result;
};
复杂度分析
| 复杂度类型 | 朴素解法 | 优化解法 |
|---|---|---|
| 时间复杂度 | O(n × q) | O(n + q) |
| 空间复杂度 | O(1) | O(1) |
其中 n 是数组长度,q 是查询次数。优化解法通过维护偶数和避免了重复计算,将时间复杂度从 O(n × q) 降低到 O(n + q)。