简体   繁体   中英

How to get sums of subarrays

While solving online code exercises, I came across this one:

Given a 1-dimensional array of numbers and the number of queries, where each query has start index a , end index b and a number c , find the sum of numbers between indexes a and b (inclusive). For each occurrence of zero within the range [a,b] , add the value of c to the sum. For example, numbers = [4,6,0,10] , queries = [1,3,20] => for this example we need to get the sum of [4,6,0] (indexes 1-3), and because [4,6,0] has 0, we also need to add 20.

This is my code so far:

function findSum(numbers, queries) {
//declare empty  array that will store the numbers
    let arr = []
// declare initial sum

    let sum = 0;
// get the last element of queries (c)
    let lastElement = queries[0].pop()

// loop through queries and push numbers to arr, to sum them in the end
    queries[0].slice(0, 2).forEach(x => {
        arr.push(numbers[x - 1])
    })
// check if arr has 0
    let zero = arr.filter(el => el === 0)

// if arr has 0, according to the instructions we need to add the c of the q
    if (zero.length != 0) {
        sum = arr.reduce((a, b) => a + b, 0) + lastElement
    }
    else {
        sum = arr.reduce((a, b) => a + b, 0)
    }
    return sum
}

My code works if queries is an array, but in some test cases queries may be array of arrays like [ [ 2, 2, 20 ], [ 1, 2, 10 ] ] . I don't know know how to check the numbers in case if queries is array of arrays. Any suggestions are greatly appreciated.

in some test cases queries may be array of arrays

I would expect that this would always be the case, not just in some cases. This is also clear from your code:

queries[0].pop()

This assumes a 2-dimensional array. The problem is not that you sometimes get a 1-dimensional array and other times a 2-dimensional array, The problem is that although you always get a 2-dimensional array, your code is only looking at the first query -- the one that sits at queries[0] .

Instead, you should loop over all queries.

I also assume that the return value of your function must be an array , having an answer for each of the queries. This means that you probably want to have code like this:

function findSum(numbers, queries) {
    return queries.map(query => {
        // solve the single query
        
        return sum;
    });
}

Note that your code is not making the sum correctly, as your arr will have a length of 2 ( arr.push(numbers[x - 1]) is executed exactly twice), yet the query could indicate a range with 100 values and you should derive the sum of those 100 values, not just of two.

But even if you fix all that, you'll end up with an inefficient solution that will have to iterate over many values in the input array multiple times. This needs a smarter approach.

Try to think of a way to analyse the input before processing any queries yet. Would there be something useful you could build that would help to quickly get a sum of a subarray without having to iterate that subsection again ?

Here are some hints:

Hint #1

Use the following truth:
sum(numbers.slice(start, end)) == sum(numbers.slice(0, end)) - sum(numbers.slice(0, start - 1))

Hint #2

What if you would know the sum from the start of the array to any given index? Like a running sum... So for numbers=[4, 8, 0, 3] you would know [4, 12, 12, 15] . Would that help in calculating a sum for a certain range of [start, end] ?

Hint #3

How could you apply the same principle for the special treatment of zeroes?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM