Maximum Subarray — Solution in Python, Java & C++
Maximum Subarray solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. A medium problem.
Maximum Subarray is a medium coding problem on arrays, dynamic programming and divide and conquer, asked in Morgan Stanley, Atlassian, Zomato and HCL interviews.
- Difficulty: Medium
- Topics: Arrays, Dynamic Programming, Divide and Conquer
- Asked at: Morgan Stanley, Atlassian, Zomato, HCL, Arcesium, Mphasis, Tech Mahindra
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
Given an integer array nums, find the contiguous subarray (containing at least one number) with the largest sum, and return that sum.
Example 1
Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: [4,-1,2,1] sums to 6.
Example 2
Input: nums = [5,4,-1,7,8]
Output: 23
Constraints
1 <= nums.length <= 30-100 <= nums[i] <= 100
Hints for Maximum Subarray
Hint 1
Kadane: best subarray ending here = max(x, previous best ending + x).
Hint 2
Track the global maximum as you sweep.
How to solve Maximum Subarray
Kadane's algorithm. Sweep the array asking one question at each position: is it better to extend the best subarray ending at the previous index, or to start fresh here? The answer is local — extend only if the running sum is still helping — and the global best is the largest of those per-position bests.
Approach
- Seed both the running sum and the best answer with the first element.
- For each later element, set
cur = max(element, cur + element). - Update
best = max(best, cur). - Return
bestafter the sweep.
Why it works
cur is exactly the largest sum of a subarray ending at the current index. Such a subarray either is the single element or extends the best one ending at the previous index — nothing else is possible, since it must be contiguous. Taking the maximum of these values over all endpoints therefore covers every subarray exactly once, which is why one pass suffices. Restarting when the running sum turns negative is the same statement: a negative prefix can only hurt whatever follows.
Complexity
- Time —
O(n) - Space —
O(1)
Pitfalls
- Seed with
nums[0], not0. An all-negative array must return its largest (least negative) element, and a zero seed wrongly returns0. - The subarray must be non-empty, which is what makes the seeding matter.
- Update
beston every step, not only when restarting. cur = max(element, cur + element)— comparing against the element itself is what performs the restart.
Reference solution
Python
from typing import List
def maxSubArray(nums: List[int]) -> int:
best = cur = nums[0]
for x in nums[1:]:
cur = max(x, cur + x)
best = max(best, cur)
return bestJava
public static int maxSubArray(int[] nums) {
int cur = nums[0], best = nums[0];
for (int i = 1; i < nums.length; i++) {
cur = Math.max(nums[i], cur + nums[i]);
if (cur > best) best = cur;
}
return best;
}C++
int maxSubArray(vector<int>& nums) {
int cur = nums[0], best = nums[0];
for (int i = 1; i < (int) nums.size(); i++) {
cur = max(nums[i], cur + nums[i]);
if (cur > best) best = cur;
}
return best;
}JavaScript
var maxSubArray = function(nums) {
let best = nums[0], cur = nums[0];
for (let i = 1; i < nums.length; i++) {
cur = Math.max(nums[i], cur + nums[i]);
best = Math.max(best, cur);
}
return best;
};Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 1199 arrays problems · the whole catalogue
Learn the technique: Arrays · Dynamic Programming