Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Python Program to solve Maximum Subarray Problem using Kadane's Algorithm
The Maximum Subarray Problem finds the contiguous subarray within a one-dimensional array of numbers that has the largest sum. Kadane's Algorithm solves this problem efficiently in O(n) time complexity using dynamic programming principles.
Understanding Kadane's Algorithm
Kadane's algorithm maintains two variables: the maximum sum ending at the current position and the overall maximum sum seen so far. At each position, it decides whether to extend the existing subarray or start a new one.
Basic Implementation
Here's a simple version that returns only the maximum sum ?
def kadane_simple(arr):
max_ending_here = max_so_far = arr[0]
for i in range(1, len(arr)):
max_ending_here = max(arr[i], max_ending_here + arr[i])
max_so_far = max(max_so_far, max_ending_here)
return max_so_far
# Test with example array
numbers = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
result = kadane_simple(numbers)
print(f"Maximum subarray sum: {result}")
Maximum subarray sum: 6
Complete Implementation with Indices
This version tracks the start and end positions of the maximum subarray ?
def find_max_subarray(arr):
max_ending_here = max_so_far = arr[0]
start = end = 0
temp_start = 0
for i in range(1, len(arr)):
if max_ending_here < 0:
max_ending_here = arr[i]
temp_start = i
else:
max_ending_here += arr[i]
if max_ending_here > max_so_far:
max_so_far = max_ending_here
start = temp_start
end = i
return start, end, max_so_far
# Test the algorithm
numbers = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
start_idx, end_idx, max_sum = find_max_subarray(numbers)
print(f"Array: {numbers}")
print(f"Maximum subarray: {numbers[start_idx:end_idx+1]}")
print(f"Start index: {start_idx}, End index: {end_idx}")
print(f"Maximum sum: {max_sum}")
Array: [-2, 1, -3, 4, -1, 2, 1, -5, 4] Maximum subarray: [4, -1, 2, 1] Start index: 3, End index: 6 Maximum sum: 6
How It Works
The algorithm works by making a local decision at each step: either extend the current subarray or start fresh. When max_ending_here becomes negative, it's better to start a new subarray from the current element.
def kadane_with_steps(arr):
print("Step-by-step execution:")
print("Index | Element | Max_ending_here | Max_so_far")
print("-" * 50)
max_ending_here = max_so_far = arr[0]
print(f" 0 | {arr[0]:2d} | {max_ending_here:2d} | {max_so_far:2d}")
for i in range(1, len(arr)):
max_ending_here = max(arr[i], max_ending_here + arr[i])
max_so_far = max(max_so_far, max_ending_here)
print(f" {i} | {arr[i]:2d} | {max_ending_here:2d} | {max_so_far:2d}")
return max_so_far
# Demonstrate with example
numbers = [5, -3, 2, -1, 4]
result = kadane_with_steps(numbers)
print(f"\nFinal maximum sum: {result}")
Step-by-step execution: Index | Element | Max_ending_here | Max_so_far -------------------------------------------------- 0 | 5 | 5 | 5 1 | -3 | 2 | 5 2 | 2 | 4 | 5 3 | -1 | 3 | 5 4 | 4 | 7 | 7 Final maximum sum: 7
Edge Cases
The algorithm handles various edge cases including arrays with all negative numbers ?
def test_edge_cases():
test_cases = [
[5], # Single positive element
[-5], # Single negative element
[-2, -1, -3], # All negative
[1, 2, 3, 4, 5], # All positive
[0, 0, 0] # All zeros
]
for i, case in enumerate(test_cases, 1):
start, end, max_sum = find_max_subarray(case)
subarray = case[start:end+1]
print(f"Test {i}: {case}")
print(f" Maximum subarray: {subarray}, Sum: {max_sum}")
print()
test_edge_cases()
Test 1: [5] Maximum subarray: [5], Sum: 5 Test 2: [-5] Maximum subarray: [-5], Sum: -5 Test 3: [-2, -1, -3] Maximum subarray: [-1], Sum: -1 Test 4: [1, 2, 3, 4, 5] Maximum subarray: [1, 2, 3, 4, 5], Sum: 15 Test 5: [0, 0, 0] Maximum subarray: [0], Sum: 0
Time and Space Complexity
| Aspect | Complexity | Explanation |
|---|---|---|
| Time | O(n) | Single pass through the array |
| Space | O(1) | Only uses constant extra space |
Conclusion
Kadane's algorithm efficiently solves the Maximum Subarray Problem in linear time by making optimal local decisions at each step. It's a classic example of dynamic programming that maintains running maximums to find the globally optimal solution.
