Facebook Pixel

985. Sum of Even Numbers After Queries

MediumArraySimulation
Leetcode Link

Problem Description

You have an integer array nums and a queries array where each query is represented as queries[i] = [val_i, index_i].

For each query, you need to:

  1. Add val_i to the element at position index_i in the nums array (i.e., nums[index_i] = nums[index_i] + val_i)
  2. Calculate the sum of all even values in the modified nums array
  3. Store this sum as the result for this query

The task is to return an array answer where answer[i] contains the sum of even values after processing the i-th query.

How the solution works:

The key insight is to maintain a running sum s of all even numbers rather than recalculating it from scratch after each query.

The algorithm follows these steps:

  1. Initially calculate s as the sum of all even numbers in the original nums array
  2. For each query (v, i):
    • If nums[i] is currently even, subtract it from s (since it will change and may no longer be even)
    • Add v to nums[i] to update the value
    • If the new nums[i] is even, add it to s
    • Append the current value of s to the answer array

This approach efficiently tracks the sum of even numbers by only adjusting for the element that changes, rather than recalculating the entire sum each time.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The naive approach would be to recalculate the sum of all even numbers in the array after each query. However, this would require iterating through the entire array for each query, resulting in O(n * q) time complexity where n is the array length and q is the number of queries.

The key observation is that each query only modifies a single element in the array. This means that the sum of even numbers changes only based on what happens to that one element:

  1. If the element was even before the update: It contributes to the current even sum, but after adding val_i, it might become odd (removing its contribution) or remain even (changing its contribution).

  2. If the element was odd before the update: It doesn't contribute to the current even sum, but after adding val_i, it might become even (adding a new contribution) or remain odd (no change to the sum).

This leads us to the insight that we can maintain a running sum and only adjust it based on the single element that changes:

  • Before updating nums[i], check if it's even. If yes, subtract it from the running sum (removing its old contribution)
  • After updating nums[i] with nums[i] + val_i, check if the new value is even. If yes, add it to the running sum (adding its new contribution)

This way, we only need O(1) time per query instead of O(n), making the overall time complexity O(n + q) where the initial O(n) is for calculating the initial sum of even numbers.

Solution Approach

The solution uses a simulation approach with an efficient tracking mechanism for the sum of even numbers.

Implementation Steps:

  1. Initialize the even sum: First, calculate the initial sum s of all even numbers in the array:

    s = sum(x for x in nums if x % 2 == 0)

    This iterates through nums once and adds up only the even values (where x % 2 == 0).

  2. Process each query: For each query (v, i) in the queries list:

    a. Check and remove old contribution: Before modifying nums[i], check if it's currently even:

    if nums[i] % 2 == 0:
        s -= nums[i]

    If it's even, subtract it from s since we're about to change this value.

    b. Update the element: Add the query value to the element:

    nums[i] += v

    c. Check and add new contribution: After the update, check if nums[i] is now even:

    if nums[i] % 2 == 0:
        s += nums[i]

    If it's even, add the new value to s.

    d. Store the result: Append the current sum s to the answer list:

    ans.append(s)
  3. Return the results: After processing all queries, return the ans array containing the sum of even values after each query.

Time Complexity: O(n + q) where n is the length of nums (for initial sum calculation) and q is the number of queries.

Space Complexity: O(q) for storing the answer array (or O(1) if we don't count the output array as extra space).

Ready to land your dream job?

Unlock your dream job with a 3-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through a small example to illustrate the solution approach.

Given:

  • nums = [1, 2, 3, 4]
  • queries = [[1, 0], [-3, 1], [-4, 0], [2, 3]]

Initial Setup: Calculate the initial sum of even numbers in nums:

  • Even numbers: 2 (at index 1) and 4 (at index 3)
  • Initial sum s = 2 + 4 = 6

Query 1: [1, 0] - Add 1 to nums[0]

  • Current nums[0] = 1 (odd), so don't subtract from s
  • Update: nums[0] = 1 + 1 = 2
  • New nums[0] = 2 (even), so add to s: s = 6 + 2 = 8
  • Array becomes: [2, 2, 3, 4]
  • Result: 8

Query 2: [-3, 1] - Add -3 to nums[1]

  • Current nums[1] = 2 (even), so subtract from s: s = 8 - 2 = 6
  • Update: nums[1] = 2 + (-3) = -1
  • New nums[1] = -1 (odd), so don't add to s
  • Array becomes: [2, -1, 3, 4]
  • Result: 6

Query 3: [-4, 0] - Add -4 to nums[0]

  • Current nums[0] = 2 (even), so subtract from s: s = 6 - 2 = 4
  • Update: nums[0] = 2 + (-4) = -2
  • New nums[0] = -2 (even), so add to s: s = 4 + (-2) = 2
  • Array becomes: [-2, -1, 3, 4]
  • Result: 2

Query 4: [2, 3] - Add 2 to nums[3]

  • Current nums[3] = 4 (even), so subtract from s: s = 2 - 4 = -2
  • Update: nums[3] = 4 + 2 = 6
  • New nums[3] = 6 (even), so add to s: s = -2 + 6 = 4
  • Array becomes: [-2, -1, 3, 6]
  • Result: 4

Final Answer: [8, 6, 2, 4]

The key efficiency comes from only adjusting the sum based on the single element that changes in each query, rather than recalculating the entire sum of even numbers each time.

Solution Implementation

1class Solution:
2    def sumEvenAfterQueries(
3        self, nums: List[int], queries: List[List[int]]
4    ) -> List[int]:
5        # Calculate initial sum of all even numbers in the array
6        even_sum = sum(num for num in nums if num % 2 == 0)
7      
8        # Store results for each query
9        result = []
10      
11        # Process each query [value, index]
12        for value, index in queries:
13            # If the current number at index is even, remove it from even_sum
14            # (since it will be modified)
15            if nums[index] % 2 == 0:
16                even_sum -= nums[index]
17          
18            # Apply the query: add value to nums[index]
19            nums[index] += value
20          
21            # If the new number at index is even, add it to even_sum
22            if nums[index] % 2 == 0:
23                even_sum += nums[index]
24          
25            # Append current even sum to results
26            result.append(even_sum)
27      
28        return result
29
1class Solution {
2    public int[] sumEvenAfterQueries(int[] nums, int[][] queries) {
3        // Calculate initial sum of all even numbers in the array
4        int evenSum = 0;
5        for (int num : nums) {
6            if (num % 2 == 0) {
7                evenSum += num;
8            }
9        }
10      
11        // Initialize result array to store sum after each query
12        int queryCount = queries.length;
13        int[] result = new int[queryCount];
14      
15        // Process each query
16        for (int queryIndex = 0; queryIndex < queryCount; queryIndex++) {
17            int valueToAdd = queries[queryIndex][0];
18            int targetIndex = queries[queryIndex][1];
19          
20            // If the number at target index is currently even, remove it from sum
21            if (nums[targetIndex] % 2 == 0) {
22                evenSum -= nums[targetIndex];
23            }
24          
25            // Apply the query: add value to the number at target index
26            nums[targetIndex] += valueToAdd;
27          
28            // If the updated number is now even, add it to the sum
29            if (nums[targetIndex] % 2 == 0) {
30                evenSum += nums[targetIndex];
31            }
32          
33            // Store the current even sum in the result array
34            result[queryIndex] = evenSum;
35        }
36      
37        return result;
38    }
39}
40
1class Solution {
2public:
3    vector<int> sumEvenAfterQueries(vector<int>& nums, vector<vector<int>>& queries) {
4        // Calculate initial sum of all even numbers in the array
5        int evenSum = 0;
6        for (int num : nums) {
7            if (num % 2 == 0) {
8                evenSum += num;
9            }
10        }
11      
12        // Result vector to store sum of even values after each query
13        vector<int> result;
14      
15        // Process each query
16        for (const auto& query : queries) {
17            int valueToAdd = query[0];
18            int index = query[1];
19          
20            // If the current number at index is even, remove it from evenSum
21            // (since it will be modified)
22            if (nums[index] % 2 == 0) {
23                evenSum -= nums[index];
24            }
25          
26            // Apply the query: add value to nums[index]
27            nums[index] += valueToAdd;
28          
29            // If the new number at index is even, add it to evenSum
30            if (nums[index] % 2 == 0) {
31                evenSum += nums[index];
32            }
33          
34            // Store the current sum of even numbers
35            result.push_back(evenSum);
36        }
37      
38        return result;
39    }
40};
41
1/**
2 * Calculates the sum of even values in the array after each query operation
3 * @param nums - The initial array of integers
4 * @param queries - Array of queries where each query is [value, index]
5 * @returns Array containing sum of even numbers after each query
6 */
7function sumEvenAfterQueries(nums: number[], queries: number[][]): number[] {
8    // Calculate initial sum of all even numbers in the array
9    let evenSum: number = nums.reduce((accumulator: number, currentValue: number) => {
10        return accumulator + (currentValue % 2 === 0 ? currentValue : 0);
11    }, 0);
12  
13    // Array to store results after each query
14    const results: number[] = [];
15  
16    // Process each query
17    for (const [valueToAdd, targetIndex] of queries) {
18        // If the current value at target index is even, remove it from the sum
19        // (since it will be modified)
20        if (nums[targetIndex] % 2 === 0) {
21            evenSum -= nums[targetIndex];
22        }
23      
24        // Apply the query: add value to the element at target index
25        nums[targetIndex] += valueToAdd;
26      
27        // If the new value at target index is even, add it to the sum
28        if (nums[targetIndex] % 2 === 0) {
29            evenSum += nums[targetIndex];
30        }
31      
32        // Store the current sum of even numbers
33        results.push(evenSum);
34    }
35  
36    return results;
37}
38

Time and Space Complexity

The time complexity is O(n + m), where n is the length of the array nums and m is the length of the array queries.

  • The initial sum computation sum(x for x in nums if x % 2 == 0) iterates through all n elements of nums, contributing O(n) time.
  • The for loop processes each of the m queries, and for each query, it performs constant time operations:
    • Checking if nums[i] % 2 == 0 takes O(1)
    • Subtracting from s takes O(1)
    • Adding to nums[i] takes O(1)
    • Checking the updated value's parity takes O(1)
    • Adding to s takes O(1)
    • Appending to ans takes O(1) amortized
  • Therefore, processing all queries takes O(m) time.

The total time complexity is O(n) + O(m) = O(n + m).

The space complexity is O(1) if we ignore the space consumed by the answer array ans. The only extra space used is for the variable s which stores the running sum of even numbers, requiring constant space.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Forgetting to Remove the Old Even Value Before Update

One of the most common mistakes is forgetting to subtract the current even value from the sum before modifying it. This leads to incorrect sums because the old value remains in the sum even after it's been changed.

Incorrect approach:

# Wrong: Only adding new even values without removing old ones
for value, index in queries:
    nums[index] += value
    if nums[index] % 2 == 0:
        even_sum += nums[index]  # This adds the entire new value, not the change
    result.append(even_sum)

Why it fails: If nums[index] was even before the update (say 4) and remains even after (say 6), the sum would incorrectly include both 4 and 6, when it should only have 6.

2. Recalculating the Entire Sum After Each Query

While this gives correct results, it's inefficient and defeats the purpose of the optimized approach.

Inefficient approach:

# Correct but inefficient: O(n*q) time complexity
for value, index in queries:
    nums[index] += value
    even_sum = sum(num for num in nums if num % 2 == 0)  # Recalculates entire sum
    result.append(even_sum)

Why it's problematic: This approach has O(n*q) time complexity instead of O(n+q), making it slow for large inputs.

3. Incorrect Handling of Odd-to-Even and Even-to-Odd Transitions

Not properly handling all four possible transitions:

  • Even → Even (subtract old, add new)
  • Even → Odd (subtract old)
  • Odd → Even (add new)
  • Odd → Odd (no change to sum)

Solution to avoid these pitfalls:

Always follow this pattern:

  1. Check if current value is even → if yes, subtract from sum
  2. Update the value
  3. Check if new value is even → if yes, add to sum

This handles all transition cases correctly and efficiently.

Discover Your Strengths and Weaknesses: Take Our 3-Minute Quiz to Tailor Your Study Plan:

How does quick sort divide the problem into subproblems?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More