|
1 | 1 | /**
|
2 |
| - * Dynamic Programming solution. |
| 2 | + * Dynamic Programming solution using Kadane's algorithm. |
3 | 3 | * Complexity: O(n)
|
4 | 4 | *
|
5 | 5 | * @param {Number[]} inputArray
|
6 | 6 | * @return {Number[]}
|
7 | 7 | */
|
8 | 8 | export default function dpMaximumSubarray(inputArray) {
|
9 |
| - // Check if all elements of inputArray are negative ones and return the highest |
10 |
| - // one in this case. |
11 |
| - let allNegative = true; |
12 |
| - let highestElementValue = null; |
13 |
| - for (let i = 0; i < inputArray.length; i += 1) { |
14 |
| - if (inputArray[i] >= 0) { |
15 |
| - allNegative = false; |
16 |
| - } |
| 9 | + // Use Kadane's algorithm to generate list of maximum sums ending/beginning at index. |
| 10 | + const endMax = inputArray.reduce((a, x, i) => a.concat([x + Math.max(0, a[i - 1] || 0)]), []); |
| 11 | + const begMax = inputArray.reduceRight((a, x) => [x + Math.max(0, a[0] || 0)].concat(a), []); |
17 | 12 |
|
18 |
| - if (highestElementValue === null || highestElementValue < inputArray[i]) { |
19 |
| - highestElementValue = inputArray[i]; |
20 |
| - } |
21 |
| - } |
| 13 | + // Obtain the maximum value for the sum of subarrays. |
| 14 | + const maxVal = begMax.reduce((acc, val) => Math.max(acc, val), -Infinity); |
22 | 15 |
|
23 |
| - if (allNegative && highestElementValue !== null) { |
24 |
| - return [highestElementValue]; |
25 |
| - } |
26 |
| - |
27 |
| - // Let's assume that there is at list one positive integer exists in array. |
28 |
| - // And thus the maximum sum will for sure be grater then 0. Thus we're able |
29 |
| - // to always reset max sum to zero. |
30 |
| - let maxSum = 0; |
31 |
| - |
32 |
| - // This array will keep a combination that gave the highest sum. |
33 |
| - let maxSubArray = []; |
34 |
| - |
35 |
| - // Current sum and subarray that will memoize all previous computations. |
36 |
| - let currentSum = 0; |
37 |
| - let currentSubArray = []; |
38 |
| - |
39 |
| - for (let i = 0; i < inputArray.length; i += 1) { |
40 |
| - // Let's add current element value to the current sum. |
41 |
| - currentSum += inputArray[i]; |
42 |
| - |
43 |
| - if (currentSum < 0) { |
44 |
| - // If the sum went below zero then reset it and don't add current element to max subarray. |
45 |
| - currentSum = 0; |
46 |
| - // Reset current subarray. |
47 |
| - currentSubArray = []; |
48 |
| - } else { |
49 |
| - // If current sum stays positive then add current element to current sub array. |
50 |
| - currentSubArray.push(inputArray[i]); |
51 |
| - |
52 |
| - if (currentSum > maxSum) { |
53 |
| - // If current sum became greater then max registered sum then update |
54 |
| - // max sum and max subarray. |
55 |
| - maxSum = currentSum; |
56 |
| - maxSubArray = currentSubArray.slice(); |
57 |
| - } |
58 |
| - } |
59 |
| - } |
60 |
| - |
61 |
| - return maxSubArray; |
| 16 | + // Extract indices of maximum value from array & use them to slice input. |
| 17 | + const maxCmp = val => (val === maxVal); |
| 18 | + return inputArray.slice(begMax.findIndex(maxCmp), endMax.findIndex(maxCmp) + 1); |
62 | 19 | }
|
0 commit comments