Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made maximum subarray solution more terse #160

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 9 additions & 52 deletions src/algorithms/sets/maximum-subarray/dpMaximumSubarray.js
Original file line number Diff line number Diff line change
@@ -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);
}