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
Largest sum of subarrays in JavaScript
Finding the maximum sum subarray is a classic algorithmic problem in JavaScript. Given an array of numbers, we need to find the contiguous subarray with the largest sum. This problem is commonly known as the Maximum Subarray Problem and has practical applications in data analysis and optimization.
Problem Statement
Given an array of integers, find the contiguous subarray with the maximum sum. For example, given the array:
[-3, 4, 2, -1, 6, -5, 3, -2, 7, 1]
The maximum subarray sum would be:
15
This comes from the subarray [4, 2, -1, 6, -5, 3, -2, 7, 1].
Approaches
We'll explore four different approaches to solve this problem:
Brute Force
Kadane's Algorithm (Dynamic Programming)
Divide and Conquer
Prefix Sum
Method 1: Brute Force
The brute force approach examines all possible subarrays and calculates their sums. We use three nested loops to generate every subarray and track the maximum sum found.
Example
function findMaxSubarraySumBruteForce(arr) {
let maxSum = -Infinity;
for (let i = 0; i < arr.length; i++) {
for (let j = i; j < arr.length; j++) {
let sum = 0;
for (let k = i; k <= j; k++) {
sum += arr[k];
}
maxSum = Math.max(maxSum, sum);
}
}
return maxSum;
}
const arr = [-3, 4, 2, -1, 6, -5, 3, -2, 7, 1];
console.log(findMaxSubarraySumBruteForce(arr));
15
Time Complexity: O(n³), Space Complexity: O(1)
Method 2: Kadane's Algorithm (Dynamic Programming)
Kadane's algorithm is the most efficient approach, solving the problem in O(n) time. It maintains two variables: the maximum sum ending at the current position and the overall maximum sum seen so far.
Example
function findMaxSubarraySumKadane(arr) {
let maxSoFar = arr[0];
let maxEndingHere = arr[0];
for (let i = 1; i < arr.length; i++) {
maxEndingHere = Math.max(arr[i], maxEndingHere + arr[i]);
maxSoFar = Math.max(maxSoFar, maxEndingHere);
}
return maxSoFar;
}
const arr = [-3, 4, 2, -1, 6, -5, 3, -2, 7, 1];
console.log(findMaxSubarraySumKadane(arr));
15
Time Complexity: O(n), Space Complexity: O(1)
Method 3: Divide and Conquer
This approach recursively divides the array into smaller parts. The maximum subarray can be in the left half, right half, or cross the middle point.
Example
function findMaxSubarraySumDivideAndConquer(arr, low, high) {
if (low === high) {
return arr[low];
}
const mid = Math.floor((low + high) / 2);
const maxLeft = findMaxSubarraySumDivideAndConquer(arr, low, mid);
const maxRight = findMaxSubarraySumDivideAndConquer(arr, mid + 1, high);
const maxCrossing = findMaxCrossingSum(arr, low, mid, high);
return Math.max(maxLeft, maxRight, maxCrossing);
}
function findMaxCrossingSum(arr, low, mid, high) {
let leftSum = -Infinity;
let sum = 0;
for (let i = mid; i >= low; i--) {
sum += arr[i];
if (sum > leftSum) {
leftSum = sum;
}
}
let rightSum = -Infinity;
sum = 0;
for (let i = mid + 1; i <= high; i++) {
sum += arr[i];
if (sum > rightSum) {
rightSum = sum;
}
}
return leftSum + rightSum;
}
const arr = [-3, 4, 2, -1, 6, -5, 3, -2, 7, 1];
console.log(findMaxSubarraySumDivideAndConquer(arr, 0, arr.length - 1));
15
Time Complexity: O(n log n), Space Complexity: O(log n)
Method 4: Prefix Sum
This approach uses prefix sums to find the maximum subarray. The key insight is that the maximum subarray sum equals the difference between the current prefix sum and the minimum prefix sum encountered so far.
Example
function findMaxSubarraySumPrefixSum(arr) {
let maxSum = -Infinity;
let minPrefixSum = 0;
let prefixSum = 0;
for (let i = 0; i < arr.length; i++) {
prefixSum += arr[i];
maxSum = Math.max(maxSum, prefixSum - minPrefixSum);
minPrefixSum = Math.min(minPrefixSum, prefixSum);
}
return maxSum;
}
const arr = [-3, 4, 2, -1, 6, -5, 3, -2, 7, 1];
console.log(findMaxSubarraySumPrefixSum(arr));
15
Time Complexity: O(n), Space Complexity: O(1)
Comparison
| Method | Time Complexity | Space Complexity | Best Use Case |
|---|---|---|---|
| Brute Force | O(n³) | O(1) | Small arrays, educational purposes |
| Kadane's Algorithm | O(n) | O(1) | Most practical applications |
| Divide and Conquer | O(n log n) | O(log n) | When modification tracking is needed |
| Prefix Sum | O(n) | O(1) | When prefix sums are already available |
Conclusion
Kadane's algorithm is the preferred solution for maximum subarray problems due to its optimal O(n) time complexity and constant space usage. While other approaches offer educational value or specific advantages, Kadane's algorithm provides the best balance of efficiency and simplicity for practical applications.
