I have a problem and an OK-ish solution. I hope there will be a better solution.
Problem
I have an array containing about 200,000 integers. Given the two indexes, i1 and i2, I need to calculate the sum of all the elements between i1 and i2. Each integer in an array is 1 to 4 inclusive. For instance:
a = [1, 3, 2, 4, 3, 2, 4, 1]; subsection_sum(a, 0, 3); // returns 6: (1 + 3 + 2)
This operation will be performed approximately 200,000 times, so it should be fairly quick. The simple counter in the for loop is O (n) and too slow. An array never changes after construction, so it must have a relatively expensive preprocessing step.
My best solution so far
This algorithm works in O (log n) time:
First enter the original array with zeros until its length is two. Then divide the array into two equal parts and save the sum of each of them. Then divide the array into quarters and save the sum of each of them. Then the eighth. Continue to do this until the array is partitioned into 2 element lengths. For the 8-element array above, this is done in two steps:
halves = [(a[0] + a[1] + a[2] + a[3]), (a[4] + a[5] + a[6] + a[7])] quarters = [(a[0] + a[1]), (a[2] + a[3]), (a[4] + a[5]), (a[6] + a[7])]
Then, given the two indexes, you can now work out subsection_sum in O (log n) time. For example, subsection_sum (a, 2, 7) == quarters [1] + halves [1].