122. Maximum Subarray
View on NeetCode
View on LeetCode
Problem
Given an integer array nums, find the subarray with the largest sum, and return its sum.
Example 1:
Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: The subarray [4,-1,2,1] has the largest sum 6.
Example 2:
Input: nums = [1]
Output: 1
Explanation: The subarray [1] has the largest sum 1.
Example 3:
Input: nums = [5,4,-1,7,8]
Output: 23
Explanation: The subarray [5,4,-1,7,8] has the largest sum 23.
Constraints:
1 <= nums.length <= 10^5-10^4 <= nums[i] <= 10^4
Solution
Approach 1: Kadane’s Algorithm (Greedy)
The key insight is to maintain a running sum, and if it becomes negative, reset it to 0 (start a new subarray).
Implementation
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
max_sum = nums[0]
current_sum = 0
for num in nums:
current_sum = max(num, current_sum + num)
max_sum = max(max_sum, current_sum)
return max_sum
Approach 2: Kadane’s (Alternative)
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
max_sum = float('-inf')
current_sum = 0
for num in nums:
current_sum += num
max_sum = max(max_sum, current_sum)
# Reset if sum becomes negative
if current_sum < 0:
current_sum = 0
return max_sum
Approach 3: Divide and Conquer
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
def maxCrossingSum(nums, left, mid, right):
# Max sum in left half ending at mid
left_sum = float('-inf')
curr_sum = 0
for i in range(mid, left - 1, -1):
curr_sum += nums[i]
left_sum = max(left_sum, curr_sum)
# Max sum in right half starting from mid+1
right_sum = float('-inf')
curr_sum = 0
for i in range(mid + 1, right + 1):
curr_sum += nums[i]
right_sum = max(right_sum, curr_sum)
return left_sum + right_sum
def maxSubArrayHelper(nums, left, right):
if left == right:
return nums[left]
mid = (left + right) // 2
left_max = maxSubArrayHelper(nums, left, mid)
right_max = maxSubArrayHelper(nums, mid + 1, right)
cross_max = maxCrossingSum(nums, left, mid, right)
return max(left_max, right_max, cross_max)
return maxSubArrayHelper(nums, 0, len(nums) - 1)
Complexity Analysis
Kadane’s Algorithm:
- Time Complexity: O(n), single pass through array.
- Space Complexity: O(1), constant extra space.
Divide and Conquer:
- Time Complexity: O(n log n), similar to merge sort.
- Space Complexity: O(log n) for recursion stack.
Key Insights
-
Kadane’s Algorithm: Classic greedy approach for maximum subarray problem.
-
Greedy Choice: At each position, decide whether to extend current subarray or start a new one.
-
Local vs Global: Track both current subarray sum (local) and overall maximum (global).
-
Reset on Negative: If current sum becomes negative, it won’t help future subarrays, so reset to 0.
-
Alternative View:
current_sum = max(num, current_sum + num)- either start fresh at num or extend current subarray. -
Always Include Element: At each step, we must include the current element in some decision.