views:

292

answers:

2

Given an array. How can we find sum of elements in index interval (i, j) in constant time. You are allowed to use extra space.
Example:
A: 3 2 4 7 1 -2 8 0 -4 2 1 5 6 -1
length = 14

int getsum(int* arr, int i, int j, int len);
// suppose int array "arr" is initialized here
int sum = getsum(arr, 2, 5, 14);

sum should be 10 in constant time.

+5  A: 

It cannot be done in constant time unless you store the information.

You would have to do something like specially modify the array to store, for each index, the sum of all values between the start of the array and this index, then using subtraction on the range to get the difference in sums.

However, nothing in your code sample seems to allow this. The array is created by the user (and can change at any time) and you have no control over it.

Any algorithm that needs to scan a group of elements in a sequential unsorted list will be O(n).

paxdiablo
memoization isn't crazy.
Matt Ellen
Yes, it is, in the context of adding up less than 15 integers :-)
paxdiablo
You don't need to store 105 integers for a 14-integer array. You can get by with cumulative sums and subtraction.
David Thornley
@David, see para 3, I covered that (as did Pavel, in a much clearer fashion). But it's still not possible *unless you can control the array*. Otherwise you have to pre-compute the values every time the function is called, at which point you may as well not pre-compute at all.
paxdiablo
@paxdiablo: Perfectly understood, but why the second paragraph? That's what attracted my eye. Other than that, it's an excellent answer.
David Thornley
@paxdiablo: fair point :)
Matt Ellen
@David, that was my first thought and I often leave in brain-f*rts for prosperity :-) The third para was added in an edit later on when I had some more chance to think about it (it's 4am over here, I'm only up because the kids are having nightmares, so I may be a little tired). I'll get rid of it though now it's not that much different from Pavel's.
paxdiablo
+11  A: 

If you can spend O(n) time to "prepare" the auxiliary information, based on which you would be able calculate sums in O(1), you could easily do it.

Preparation (O(n)):

aux[0] = 0;
foreach i in (1..LENGTH) {
  aux[i] = aux[i-1] + arr[i];
}

Query (O(1)), arr is numerated from 1 to LENGTH:

sum(i,j) = aux[j] - aux[i-1];

I think it was the intent, because, otherwise, it's impossible: for any length to calculate sum(0,length-1) you should have scanned the whole array; this takes linear time, at least.

Pavel Shved
I think it should be aux[j] - aux[i-1].
Lluis Martinez
@Lluis, if we numerate the array from 1 (which is the case), then it should.
Pavel Shved