Reputation: 13
For context, this is the problem statement in Codewars: Problem Statement
It's essentially the classic 'Find the maximum subarray sum' problem, though with the important added detail of the fact that a '0' should be returned given an array of all negative numbers, instead of just the largest negative number value.
To begin with, I'm fully aware that this solution is not a terribly good or efficient one. That being said, the logic to me still makes sense so I don't quite understand why it works for certain inputs and not others. I can't provide the inputs for which this program is invalid due to the fact that the test cases are hidden in Codewars.
I've tried running the code using examples like;
Again, I just wanna know the logic behind why this code is incorrect. I'm not looking for an alternative solution that is correct (I'm already aware of the existence of Kadane's algorithm now). This was my first blind attempt at solving this problem so I'd really like to know what I did wrong so that I can learn from it.
def max_sequence(arr):
max_sum = 0
max_subarr_index = 0
for i, val in enumerate(arr):
max_sum = max(max_sum, sum(arr[max_subarr_index:i+1]), val)
if max_sum == val:
max_subarr_index = i
return max_sum
Upvotes: 1
Views: 420
Reputation:
The flaw lies in the fact that max_sum
has a dual usage in your algorithm. It's used to:
keep the maximum found sum over the so far explored array
update max_subarr_index
if the larger array starts directly at index i
instead of max_subarr_index
For the first point, your algorithm works just fine. For the second it fails, because max_sum
needn't have anything to do with the subarray you're currently looking at. E.g.:
arr = [3, -4, 1, 1, ...]
Now for i = 3
the variables look like this:
max_sum = 3
max_subarr_index = 0
I.e. the algorithm still "thinks" the maximum subarray starts at index 0 and has the sum 3. However the maximum subarray ending at index 3 is actually [1, 1]
with max_subarr_index = 2
. I.e. there's actually two maximum subarrays:
[3]
for i = 3
)[1, 1]
for i = 3
)You can fix this by updating max_subarr_index
based only on the maximum of val
and sum(arr[max_subarr_index:i+1])
:
def max_sequence(arr):
max_sum = 0
max_subarr_index = 0
for i, val in enumerate(arr):
# update max_subarr_index based on sum of "current" max subarray
tmp = max(sum(arr[max_subarr_index:i+1]), val)
if tmp == val:
max_subarr_index = i
# global maximum found so far
max_sum = max(max_sum, tmp)
return max_sum
Upvotes: 1