Given an array of numbers, return the maximum sum of any continous subarray of numbers.
Input: [1, 2, 3, -7, 4, 5] Output: 9 The subarray with the highest sum is [4, 5] with a sum of 9
Solution | Time | Space |
---|---|---|
Brute force | O(n2) | O(1) |
Divide and conquer | O(n log n) | O(n) |
Dynamic programming | O(n) | O(n) |
Kadane's algorithm | O(n) | O(1) |
To find the maximum subarray sum:
The max sum after checking all subarrays is the maximum subarray sum
def maximum_subarray_sum(numbers) n = numbers.length max_sum = 0 (0 .. n-1).each do |i| sum = numbers[i] max_sum = [max_sum, sum].max (i+1 .. n-1).each do |j| sum += numbers[j] max_sum = [max_sum, sum].max end end max_sum end
Time | O(n2) | Checking all O(n2) possible subarrays |
Space | O(1) | The sum and max sum |
The maximum subarray sum can exist in 1 of 3 places:
The divide and conquer approach recursively checks smaller subarrays and returns the highest sum found.
def maximum_subarray_sum(numbers) max_sum(numbers, 0, numbers.length-1) end def max_sum(numbers, low, high) return numbers[low] if low >= high mid = (low + high) / 2 [ max_sum(numbers, low, mid), max_sum(numbers, mid + 1, high), cross_sum(numbers, low, high), ].max end def cross_sum(numbers, low, high) mid = (low + high) / 2 max_sum = sum = numbers[mid] (mid - 1).downto(low).each do |i| sum += numbers[i] max_sum = [max_sum, sum].max end sum = max_sum (mid + 1).upto(high).each do |i| sum += numbers[i] max_sum = [max_sum, sum].max end max_sum end
Time | O(n log n) | Stack depth of O(log n) each checking O(n) values |
Space | O(log n) | Max stack depth of O(log n) |
def maximum_subarray_sum(numbers) n = numbers.length max_sums = Array.new(n) max_sums[0] = max_sum = numbers[0] (1 .. n-1).each do |i| max_sums[i] = numbers[i] if max_sums[i-1] > 0 max_sums[i] += max_sums[i-1] end max_sum = [max_sum, max_sums[i]].max end max_sum end
Time | O(n) | Loop through all values in the input array once |
Space | O(n) | Space for an n-length array |
def maximum_subarray_sum(numbers) n = numbers.length max_sum = sum = numbers[0] (1 .. n-1).each do |i| if sum + numbers[i] > numbers[i] sum += numbers[i] else sum = numbers[i] end max_sum = [max_sum, sum].max end max_sum end
Time | O(n) | Loop through all values in the input array once |
Space | O(1) | The sum and max sum |