3.9 Maximum Subarray
3.9.1 Problem Metadata
- Platform: LeetCode
- Problem ID: 53
- Difficulty: Easy
- URL: https://leetcode.com/problems/lc-maximum-subarray/
- Tags: Grind 75, Blind 75, NeetCode 150
- Techniques: Dynamic Programming, Tabulation, Array
3.9.2 Description
Given an integer array nums, find the contiguous subarray with the largest sum and return that sum.
3.9.3 Examples
Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
3.9.5 Solution - Kadane’s Algorithm
3.9.5.1 Walkthrough
This solution uses Kadane’s Algorithm (see Kadane’s Algorithm), a classic dynamic programming technique for finding the maximum sum of a contiguous subarray.
Core Strategy:
The key insight is to maintain a running state representing the best subarray ending at the current position. At each element, we make a critical decision:
- Start fresh from the current element (begin a new subarray)
- Extend the previous subarray by including the current element
This decision is captured by the recurrence relation:
current = max(nums[i], current + nums[i])
where current represents the maximum sum of a subarray ending at index i.
Why max(nums[i], current + nums[i])?
nums[i]: Start a new subarray from this elementcurrent + nums[i]: Extend the previous best subarray
If the previous sum (current) is negative, adding it to nums[i] would only decrease the value. Starting fresh from nums[i] gives a better result.
Step-by-step execution:
For the array [-2, 1, -3, 4, -1, 2, 1, -5, 4]:
i=0: nums[0]=-2
current = -2 (first element)
maxSum = -2
i=1: nums[1]=1
current = max(1, -2+1) = max(1, -1) = 1 (start fresh!)
maxSum = max(-2, 1) = 1
i=2: nums[2]=-3
current = max(-3, 1+(-3)) = max(-3, -2) = -2 (extend)
maxSum = max(1, -2) = 1
i=3: nums[3]=4
current = max(4, -2+4) = max(4, 2) = 4 (start fresh!)
maxSum = max(1, 4) = 4
i=4: nums[4]=-1
current = max(-1, 4+(-1)) = max(-1, 3) = 3 (extend)
maxSum = max(4, 3) = 4
i=5: nums[5]=2
current = max(2, 3+2) = max(2, 5) = 5 (extend)
maxSum = max(4, 5) = 5
i=6: nums[6]=1
current = max(1, 5+1) = max(1, 6) = 6 (extend)
maxSum = max(5, 6) = 6
i=7: nums[7]=-5
current = max(-5, 6+(-5)) = max(-5, 1) = 1 (extend)
maxSum = max(6, 1) = 6
i=8: nums[8]=4
current = max(4, 1+4) = max(4, 5) = 5 (extend)
maxSum = max(6, 5) = 6
Result: 6 (from subarray [4,-1,2,1])
Key Insight: At each position, we only need to know the best subarray ending at the previous position. We don’t need to track all possible subarrays, making this approach highly efficient.
3.9.5.2 Analysis
- Time Complexity: O(n)
- Single pass through the array
- Each element is visited exactly once
- Each iteration performs constant-time operations (two comparisons and assignments)
- No nested loops or recursion
- This is optimal since we must examine every element at least once
- Space Complexity: O(1)
- Only uses two variables (
currentandmaxSum) regardless of input size - No additional data structures needed
- No recursion stack space
- This is optimal for the iterative approach
- Only uses two variables (
Why This Approach is Optimal:
- We cannot do better than O(n) time since we must examine every element
- We cannot use less than O(1) space while maintaining necessary state
- Kadane’s algorithm achieves both optimal time and space complexity
3.9.5.3 Implementation Steps
Initialization:
- Initialize
current = nums[0](maximum sum of subarray ending at position 0) - Initialize
maxSum = nums[0](global maximum sum found so far)
Main Loop (iterate from index 1 to n-1):
For each element nums[i]:
- Update current (best subarray ending at position i):
- Compare two choices:
- Start fresh:
nums[i](begin new subarray from current element) - Extend:
current + nums[i](add current element to previous subarray)
- Start fresh:
- Set
current = Math.max(nums[i], current + nums[i]) - Critical insight: If
currentwas negative, starting fresh is always better
- Compare two choices:
- Update global maximum:
- Set
maxSum = Math.max(maxSum, current) - Track the best result seen across all positions
- Set
Return:
- Return
maxSum(the maximum subarray sum)