From 47dff8d93bd0f2eb9300900642c781acedc9ca3d Mon Sep 17 00:00:00 2001 From: Bruce Feldman <bfeldman@sunriselabs.com> Date: Sat, 11 Aug 2018 18:05:54 -0400 Subject: [PATCH] Made maximum subarray solution more terse --- .../maximum-subarray/dpMaximumSubarray.js | 61 +++---------------- 1 file changed, 9 insertions(+), 52 deletions(-) diff --git a/src/algorithms/sets/maximum-subarray/dpMaximumSubarray.js b/src/algorithms/sets/maximum-subarray/dpMaximumSubarray.js index 12f919d737..342e7f10e8 100644 --- a/src/algorithms/sets/maximum-subarray/dpMaximumSubarray.js +++ b/src/algorithms/sets/maximum-subarray/dpMaximumSubarray.js @@ -1,62 +1,19 @@ /** - * Dynamic Programming solution. + * Dynamic Programming solution using Kadane's algorithm. * Complexity: O(n) * * @param {Number[]} inputArray * @return {Number[]} */ export default function dpMaximumSubarray(inputArray) { - // Check if all elements of inputArray are negative ones and return the highest - // one in this case. - let allNegative = true; - let highestElementValue = null; - for (let i = 0; i < inputArray.length; i += 1) { - if (inputArray[i] >= 0) { - allNegative = false; - } + // Use Kadane's algorithm to generate list of maximum sums ending/beginning at index. + const endMax = inputArray.reduce((a, x, i) => a.concat([x + Math.max(0, a[i - 1] || 0)]), []); + const begMax = inputArray.reduceRight((a, x) => [x + Math.max(0, a[0] || 0)].concat(a), []); - if (highestElementValue === null || highestElementValue < inputArray[i]) { - highestElementValue = inputArray[i]; - } - } + // Obtain the maximum value for the sum of subarrays. + const maxVal = begMax.reduce((acc, val) => Math.max(acc, val), -Infinity); - if (allNegative && highestElementValue !== null) { - return [highestElementValue]; - } - - // Let's assume that there is at list one positive integer exists in array. - // And thus the maximum sum will for sure be grater then 0. Thus we're able - // to always reset max sum to zero. - let maxSum = 0; - - // This array will keep a combination that gave the highest sum. - let maxSubArray = []; - - // Current sum and subarray that will memoize all previous computations. - let currentSum = 0; - let currentSubArray = []; - - for (let i = 0; i < inputArray.length; i += 1) { - // Let's add current element value to the current sum. - currentSum += inputArray[i]; - - if (currentSum < 0) { - // If the sum went below zero then reset it and don't add current element to max subarray. - currentSum = 0; - // Reset current subarray. - currentSubArray = []; - } else { - // If current sum stays positive then add current element to current sub array. - currentSubArray.push(inputArray[i]); - - if (currentSum > maxSum) { - // If current sum became greater then max registered sum then update - // max sum and max subarray. - maxSum = currentSum; - maxSubArray = currentSubArray.slice(); - } - } - } - - return maxSubArray; + // Extract indices of maximum value from array & use them to slice input. + const maxCmp = val => (val === maxVal); + return inputArray.slice(begMax.findIndex(maxCmp), endMax.findIndex(maxCmp) + 1); }