Max Positive Slice Sum

def max_pos_slice_sum(arr):
  maximum = -1
  for lower, upper in enumerate_slices(arr):
    # NOTE: can this be optimized?
    maximum = max(maximum, sum(arr[lower:upper+1]))
  return maximum

def enumerate_slices(arr):
  """Find all non-negative slices of maximum length in arr."""
  i = 0
  while i < len(arr) and arr[i] < 0:
    # start from the first positive number in arr.
    i += 1

  lower = i
  while i < len(arr):
    if arr[i] < 0:
      yield lower, i-1
      # skip past all negative values until
      # the beginning of the next slice.
      while i < len(arr) and arr[i] < 0:
        i += 1
      lower = i
    else:
      i += 1
  if lower < i:
    yield lower, i-1

#Challenge

SourceLanguageRuntime
OApython\(\mathcal{O}(n)\)

Given an array A of size n, we define a slice \((P,Q)\) where \(0 \leq P \leq Q \lt 0\) and every i in \([p..q]\) (inclusive) is positive. Find the slice in A which has the largest sum.

For example in the array [1,2,-3,4,5,-6] there are slices of [1], [2], [1,2], [4], [5], [4,5] with the slice having the largest sum being [4,5].

#Solution

This problem is actually easier than it seems. While initially we're told to consider all possible slices in the array A, it's intuitively obvious that we only need to concern ourselves with the largest possible slices we can find.

For the above example of [1,2,-3,4,5,-6] we can consider a slice of [1], [2] and [1,2] seperately, but because slices consist only of positive values considering just [1,2] is guranteed to give a larger sum than [1] and [2] seperately.

Knowing that we only care about the largest slices we can form, we just need to split the array A at every continuous sequence (1 or more) of negative values we can find. For A=[1,2,-3,-4,5,6,-7] we need to split it into [1,2], [-3,-4], [5,6], [-7] and intuitively disregard the splits consisting of only negative values. My enumerate_slices method above does exactly this, calling it creates an iterator over arr which returns the lower and upper indices (inclusive) of where the splits are in arr. Then we just need to maintain a maximum and update it with the sum of each found split.