Kadane's Algorithm Maximum Subarray in DSA Python - Time & Space Complexity
We want to understand how the time needed to find the maximum sum of a continuous subarray changes as the input size grows.
How does the number of steps grow when the array gets bigger?
Analyze the time complexity of the following code snippet.
def max_subarray(arr):
max_ending_here = max_so_far = arr[0]
for x in arr[1:]:
max_ending_here = max(x, max_ending_here + x)
max_so_far = max(max_so_far, max_ending_here)
return max_so_far
This code finds the largest sum of any continuous part of the array using Kadane's Algorithm.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: A single loop that goes through each element of the array once.
- How many times: Exactly once for each element, so n times if the array has n elements.
As the array gets bigger, the number of steps grows directly with the number of elements.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps |
| 100 | About 100 steps |
| 1000 | About 1000 steps |
Pattern observation: The steps increase in a straight line as the input size grows.
Time Complexity: O(n)
This means the time to find the maximum subarray grows directly with the size of the input array.
[X] Wrong: "Since we check sums of many subarrays, the time must be quadratic O(n²)."
[OK] Correct: Kadane's Algorithm cleverly keeps track of sums as it goes, so it only needs one pass through the array, not checking all subarrays separately.
Understanding this linear time solution shows you can find efficient answers by smartly reusing information, a key skill in problem solving.
"What if we wanted to find the maximum subarray sum but also needed to return the start and end indexes? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem Kadane's Algorithm solves
Kadane's Algorithm is designed to find the maximum sum of any contiguous subarray within a given array.Step 2: Compare with other options
Options B, C, and D describe different problems unrelated to Kadane's Algorithm.Final Answer:
The maximum sum of a contiguous subarray -> Option DQuick Check:
Maximum subarray sum = maximum sum of contiguous elements [OK]
- Confusing maximum subarray sum with total array sum
- Thinking it finds minimum or longest subsequence
- Assuming it sorts the array
Solution
Step 1: Understand variable roles in Kadane's Algorithm
max_so_far tracks the maximum sum found so far, so it should start very low (negative infinity) to handle negative numbers. max_ending_here tracks current subarray sum and starts at 0.Step 2: Check each option
max_so_far = 0; max_ending_here = 0 initializes max_so_far to 0, which fails if all numbers are negative. max_so_far = 0; max_ending_here = float('inf') wrongly sets max_ending_here to positive infinity. max_so_far = null; max_ending_here = null uses null, which causes errors in arithmetic.Final Answer:
max_so_far = float('-inf'); max_ending_here = 0 -> Option CQuick Check:
Initialize max_so_far very low, max_ending_here zero [OK]
- Initializing max_so_far to 0 causes wrong results with negatives
- Using null causes type errors
- Setting max_ending_here to infinity breaks logic
def max_subarray_sum(arr):
max_so_far = float('-inf')
max_ending_here = 0
for x in arr:
max_ending_here += x
if max_so_far < max_ending_here:
max_so_far = max_ending_here
if max_ending_here < 0:
max_ending_here = 0
return max_so_far
print(max_subarray_sum([-2, 3, 2, -1, 4, -5]))Solution
Step 1: Trace the loop and update sums
Start max_so_far = float('-inf'), max_ending_here = 0
Iteration 1: x=-2, max_ending_here= -2; max_so_far updated to -2; -2<0 reset to 0 (max_so_far=-2)
Iteration 2: x=3, max_ending_here=3 > -2, max_so_far=3
Iteration 3: x=2, max_ending_here=5 >3, max_so_far=5
Iteration 4: x=-1, max_ending_here=4 <5 no update, 4>=0 no reset
Iteration 5: x=4, max_ending_here=8 >5, max_so_far=8
Iteration 6: x=-5, max_ending_here=3 <8 no update, 3>=0 no resetStep 2: Final return value
max_so_far is 8, so the function returns 8.Final Answer:
8 -> Option AQuick Check:
Max subarray sum = 8 [OK]
- Not resetting max_ending_here when negative
- Updating max_so_far incorrectly
- Miscounting sums during iteration
def max_subarray(arr):
max_so_far = 0
max_ending_here = 0
for i in range(len(arr)):
max_ending_here = max_ending_here + arr[i]
if max_so_far < max_ending_here:
max_so_far = max_ending_here
elif max_ending_here < 0:
max_ending_here = 0
return max_so_far
print(max_subarray([-3, -2, -1]))Solution
Step 1: Trace execution on [-3, -2, -1]
max_so_far=0, max_ending_here=0.
i=0, x=-3: meh=-3; 0 < -3? no; elif -3<0: yes, meh=0.
i=1, x=-2: meh=-2; no update; reset meh=0.
i=2, x=-1: meh=-1; no update; reset.
Returns 0, but correct max subarray sum is -1.Step 2: Why A and not others
Init max_so_far=0 prevents update when all negative (meh never >0). B: elif ok here (if never true, always resets). C: range correct. D: meh=0 correct.Final Answer:
max_so_far initialized to 0 causes wrong result for all negatives -> Option AQuick Check:
Init max_so_far to float('-inf') for negatives [OK]
- Initializing max_so_far to 0 fails with all negatives
- Using elif causes reset to be skipped
- Wrong loop range causes index errors
Choose the best approach.
Solution
Step 1: Understand Kadane's Algorithm extension
To find indices, track the start index of the current subarray when max_ending_here resets to 0. When max_so_far updates, record current start and end indices.Step 2: Compare with other options
Store all subarrays and pick the max sum after the loop ends is inefficient and not Kadane's approach. Use a nested loop to check all subarrays and record indices is brute force, not Kadane's. Return max_so_far only; indices cannot be found with Kadane's Algorithm is incorrect; indices can be found.Final Answer:
Track current start index when resetting max_ending_here; update global start and end when max_so_far changes -> Option BQuick Check:
Track start on reset, update indices on max update [OK]
- Ignoring index tracking in Kadane's Algorithm
- Using brute force instead of Kadane's logic
- Assuming indices can't be found with Kadane's
Ready to prove it?
Pass the test and this pattern moves unknown
