0

The input to this problem is an array A[1...n] of real numbers. Your need to find out what the highest value is that can be obtained by summing up all numbers of a contiguous subsequence A[i],A[i+1],...A[j] of A. If A does not contain negative numbers, the problem is trivial and can be solved by summing up all the elements of A. It becomes more tricky when A contains a mix of positive and negative numbers though.

For instance, for A = [-2,11,-4,13,-5,-3], the solution is 20 (11-4+13=20). For A = [-2,1,-3,4,-1,2,1,-5,4], the solution is 6 (4-1+2+1=6). The sum of the numbers of an empty subsequence is 0.

There exists a brute force solution that solves this problem in O(n^3), but it is also possible to solve the problem in linear time.

  1. Design an algorithm that solves the problem described above in linear time. Present your algorithm in pseudo-code.
  2. Briefly explain how and why your algorithm works.
  3. Give a brief explanation of why your algorithm indeed runs in linear time.
Cà phê đen
  • 1,883
  • 2
  • 21
  • 20
soapzi
  • 11
  • 1

1 Answers1

0

If we don't take any item (so the solution is an empty subarray), we have 0 as a solution. That's why the rule is:

 When running `sum` drops to `0` or below, restart summing. 

A bit tricky moment is while summing we run into a negative number:

 3, 4, 5, -1 ...

we can either leave it (and have 3 + 4 + 5 == 12) or take it hoping that positive numbers will appear soon:

3, 4, 5, -1, 100, 200, 300

to solve this ambiguity we can just memorize the best sum so far as a result and continue summing. C# implementation:

private static double Solution(IEnumerable<double> source) {
  // We can guarantee 0 (for empty subarray) 
  double result = 0;
  double sum = 0; 

  // Linear: all we have to do is to scan the collection 
  foreach (var item in source) 
    if (sum + item <= 0) // when sum drops to zero
      sum = 0;           // ... restart summing
    else {
      sum += item;

      if (sum > result)  // update the best sum so far on each decision
        result = sum;
    }

  return result;
}

Tests:

// 6
Console.WriteLine(Solution(new double[] { -2, 1, -3, 4, -1, 2, 1, -5, 4 }));
// 20
Console.WriteLine(Solution(new double[] { -2, 11, -4, 13, -5, -3 }));
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215