Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Re: Largest Sum of Consecutive Integers

by blokhead (Monsignor)
on Aug 30, 2006 at 18:53 UTC ( #570453=note: print w/replies, xml ) Need Help??

in reply to Largest Sum of Consecutive Integers

Here's a linear-time algorithm that uses a much different approach than what tye has outlined.. It's probably needlessly dense, but I'm sorry, it came out of my brain in such a form.

If you want to find the best interval within array[i..j], then there are 3 possibilities.

  • The best interval is completely contained within the left half of array[i..j]
  • The best interval is completely contained within the right half of array[i..j].
  • The best interval includes the midpoint of i..j (so it is made up of the best interval in the left half that includes the midpoint, and the best interval in the right half that includes the midpoint).
I'll define a couple of thingies here: OK, so I like to write out dynamic programming algorithms in a logic programming paradigm:
  • best(i,j) is the score of the best interval within array[i..j]
  • lbest(i,j) is the score of the best interval within array[i..j] that includes the left endpoint (i)
  • rbest(i,j) is the score of the best interval within array[i..j] that includes the right endpoint (j)
  • total(i,j) is the sum of the elements in array[i..j].
Here are the rules for the dynamic programming:
lbest(i,i) = rbest(i,i) = best(i,i) = max{ 0, array[i] } best(i,j) = max{ rbest(i,k) + lbest(k+1,j), best(i,k), best(k+1,j) }, where k = int((j+i)/2) lbest(i,j) = max{ total(i,k) + lbest(k+1,j), lbest(i,k) }, where k = int((j+i)/2) rbest(i,j) = max{ rbest(i,k) + total(k+1,j), rbest(k+1,j) }, where k = int((j+i)/2)
We can compute total(i,j) without much overhead by keeping track of an accumulation array (sums of the form array[0..j]). This takes O(n) precomputation for the accumulation sums, and we can compute total(i,j) = sum(array[0..j]) - sum(array[0..i-1]) in constant time.

To compute each lbest(i,j), we split the interval into two intervals of half the size and recurse (with constant computation at this level). So to precompute all the lbest() and rbest() values that we need takes linear time total. Then with all of the lbest() and rbest() precomputed, to compute best(i,j) also just takes two recursive calls for intervals half the size. So the whole algorithm is linear.

OK, so this is probably a lot more machinery than tye suggests, but it gets the job done. I was formulating this before I saw his reply anyway. I wrote some example code for this, but I doubt anyone cares..

There's also the usual pain associated with modifying an algorithm that computes score of the best interval (which this does) to make it return the actual interval itself. ;)


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://570453]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (11)
As of 2018-06-22 14:20 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (124 votes). Check out past polls.