【LeetCode】985. 查询后的偶数和

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的数量

方法三 剪枝二

思路与算法

不同的剪枝策略

  1. 如果当前项是偶数,计算出其余的偶数和。如果是奇数,整体的偶数和就是其余项的偶数和。
  2. 然后对当前项进行修改
  3. 修改后为偶数 则加到其余项的偶数和中去

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) 的额外空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值