This is for solving the Maximum Subarray problem, so we’ll investigate what approaches we can take to solve it.
Bruteforce
# bruteforce
maxSum = -1000000
for i in range(len(nums)):
subArraySum = 0
for j in range(i, len(nums)):
subArraySum += nums[j]
maxSum = max(maxSum, subArraySum) # careful; this is on this indent level
return maxSum
Kadane’s Algorithm
“Don’t add a negative if we don’t have to.”
subArraySum = -1000000
currentSum = 0
for i in range(len(nums)):
currentSum = nums[i] + max(currentSum, 0)
subArraySum = max(subArraySum, currentSum)
return subArraySum
This calculates it in the opposite direction to the DP solution I give; it calculates the max subarray ending with a given .
DP Solution
We can create a DP solution.
First, we’ll look at basic memoisation then go on further to optimise it. We will arrive at an algorithm which is essentially Kadane’s Algorithm but in the opposite direction; if you wrote the DP solution in the opposite direction, then you would derive Kadane’s Algorithm.
Approach
Generate an OPT function which gives us the max subarray starting from a given index .
We then ask ourselves, “do we include any more elements?”
We can answer this question by checking if the max subarray for the next element is greater than 0 or not. If it’s not, then there’s no point including it.
Memoisation
OPT = [0] * len(nums) # value (0) doesn't matter since it'll be replaced
OPT[len(nums)-1] =nums[len(nums)-1]
for i in range(len(nums)-2, -1, -1):
OPT[i] = nums[i] + max(0, OPT[i+1])
maxSubarray = -1000000
for i in range(0, len(OPT)):
maxSubarray = max(maxSubarray, OPT[i])
return maxSubarray
Only need to keep track of the OPT value immediately above.
Previous Pointer
prevMax = nums[len(nums)-1]
maxSubarray = prevMax
for i in range(len(nums)-2, -1, -1):
prevMax = nums[i] + max(0, prevMax)
maxSubarray = max(maxSubarray, prevMax)
return maxSubarray