Maximum Subarray
Problem Statement
Section titled “Problem Statement”Given an integer array nums, find the subarray with the largest sum and return its sum. A subarray is a contiguous non-empty sequence of elements within an array.
Examples
Section titled “Examples”| Input | Output | Explanation |
|---|---|---|
[-2, 1, -3, 4, -1, 2, 1, -5, 4] | 6 | Subarray [4, -1, 2, 1] has the largest sum of 6 |
[5, 4, -1, 7, 8] | 23 | Entire array [5, 4, -1, 7, 8] has the sum of 23 |
[-1] | -1 | Only one element, so return that element |
Constraints
Section titled “Constraints”1 <= nums.length <= 10^5-10^4 <= nums[i] <= 10^4
Real-World Applications
Section titled “Real-World Applications”Complexity Comparison
Section titled “Complexity Comparison”| Approach | Time | Space | Best When |
|---|---|---|---|
| Brute Force | O(n²) | O(1) | Learning, tiny arrays |
| Kadane | O(n) | O(1) | General case — fast and simple |
| Divide & Conquer | O(n log n) | O(log n) | Interview discussion |
Which approach should you learn first?
Section titled “Which approach should you learn first?”- Pick Kadane for the optimal interview solution — it is simple, O(n), and elegant.
- Pick Brute Force if you are learning how to think about subarrays.
- Pick Divide & Conquer if you want to understand the recursive pattern or are discussing trade-offs.
Best For Speed
Kadane
O(n) time · O(1) space
Learn Pattern
Brute Force
O(n²) time · O(1) space
Divide & Conquer
Recursive
O(n log n) time · O(log n) space
Approach 1: Brute Force
Section titled “Approach 1: Brute Force”Check every possible subarray by examining all pairs of start and end indices. For each starting position, consider all possible ending positions and track the maximum sum found.
⏱ Time O(n²) All pairs checked 💾 Space O(1) Constant
Solution Code
Section titled “Solution Code”from typing import List
def maximum_subarray_brute_force(nums: List[int]) -> int: """ Maximum Subarray - Brute Force approach.
Time: O(n), Space: O(1) or O(n) depending on approach """ pass
if __name__ == "__main__": # Test cases pass#include <iostream>#include <vector>#include <unordered_map>using namespace std;
class Solution {public: int maximum_subarray_brute_force(vector<int>& nums) { // Maximum Subarray - Brute Force approach return 0; }};
int main() { return 0;}import java.util.*;
class Solution { public int maximum_subarray_brute_force(int[] nums) { // Maximum Subarray - Brute Force approach return 0; }
public static void main(String[] args) { // Test cases }}/** * {@param {number[]} nums} * {@return {number}} */var maximum_subarrayBruteforce = function(nums) { // Maximum Subarray - Brute Force approach return 0;};
if (require.main === module) { // Test cases}pub fn maximum_subarray_brute_force(nums: Vec<i32>) -> i32 { // Maximum Subarray - Brute Force approach 0}
fn main() { // Test cases}package main
import "fmt"
func maximum_subarrayBruteforce(nums []int) int { // Maximum Subarray - Brute Force approach return 0}
func main() { // Test cases}Approach 2: Kadane’s Algorithm (Recommended)
Section titled “Approach 2: Kadane’s Algorithm (Recommended)”Use dynamic programming to track the maximum sum ending at the current position. If adding the current element to the previous maximum sum is worse than starting fresh, restart from the current element.
⏱ Time O(n) Single pass 💾 Space O(1) Constant
Solution Code
Section titled “Solution Code”from typing import List
def maximum_subarray_kadane(nums: List[int]) -> int: """ Maximum Subarray - Kadane approach.
Time: O(n), Space: O(1) or O(n) depending on approach """ pass
if __name__ == "__main__": # Test cases pass#include <iostream>#include <vector>#include <unordered_map>using namespace std;
class Solution {public: int maximum_subarray_kadane(vector<int>& nums) { // Maximum Subarray - Kadane approach return 0; }};
int main() { return 0;}import java.util.*;
class Solution { public int maximum_subarray_kadane(int[] nums) { // Maximum Subarray - Kadane approach return 0; }
public static void main(String[] args) { // Test cases }}/** * {@param {number[]} nums} * {@return {number}} */var maximum_subarrayKadane = function(nums) { // Maximum Subarray - Kadane approach return 0;};
if (require.main === module) { // Test cases}pub fn maximum_subarray_kadane(nums: Vec<i32>) -> i32 { // Maximum Subarray - Kadane approach 0}
fn main() { // Test cases}package main
import "fmt"
func maximum_subarrayKadane(nums []int) int { // Maximum Subarray - Kadane approach return 0}
func main() { // Test cases}Approach 3: Divide and Conquer
Section titled “Approach 3: Divide and Conquer”Divide the array into two halves and recursively find the maximum subarray in each half. The answer is either in the left half, right half, or crosses the midpoint.
⏱ Time O(n log n) Recursive depth 💾 Space O(log n) Call stack
Solution Code
Section titled “Solution Code”from typing import List
def maximum_subarray_divide_and_conquer(nums: List[int]) -> int: """ Maximum Subarray - Divide And Conquer approach.
Time: O(n), Space: O(1) or O(n) depending on approach """ pass
if __name__ == "__main__": # Test cases pass#include <iostream>#include <vector>#include <unordered_map>using namespace std;
class Solution {public: int maximum_subarray_divide_and_conquer(vector<int>& nums) { // Maximum Subarray - Divide And Conquer approach return 0; }};
int main() { return 0;}import java.util.*;
class Solution { public int maximum_subarray_divide_and_conquer(int[] nums) { // Maximum Subarray - Divide And Conquer approach return 0; }
public static void main(String[] args) { // Test cases }}/** * {@param {number[]} nums} * {@return {number}} */var maximum_subarrayDivideandconquer = function(nums) { // Maximum Subarray - Divide And Conquer approach return 0;};
if (require.main === module) { // Test cases}pub fn maximum_subarray_divide_and_conquer(nums: Vec<i32>) -> i32 { // Maximum Subarray - Divide And Conquer approach 0}
fn main() { // Test cases}package main
import "fmt"
func maximum_subarrayDivideandconquer(nums []int) int { // Maximum Subarray - Divide And Conquer approach return 0}
func main() { // Test cases}