Skip to content

Commit 82f0b5e

Browse files
committedFeb 4, 2022
Add a Divide and Conquer version of the MaxSubArray problem.
1 parent 819f38f commit 82f0b5e

File tree

8 files changed

+67
-8
lines changed

8 files changed

+67
-8
lines changed
 

‎.npmrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
engine-strict=false
1+
engine-strict=true

‎.nvmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v14

‎README.md

+3
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ algorithm is an abstraction higher than a computer program.
207207
* `B` [Best Time To Buy Sell Stocks](src/algorithms/uncategorized/best-time-to-buy-sell-stocks) - divide and conquer and one-pass examples
208208
* `A` [Permutations](src/algorithms/sets/permutations) (with and without repetitions)
209209
* `A` [Combinations](src/algorithms/sets/combinations) (with and without repetitions)
210+
* `A` [Maximum Subarray](src/algorithms/sets/maximum-subarray)
210211
* **Dynamic Programming** - build up a solution using previously found sub-solutions
211212
* `B` [Fibonacci Number](src/algorithms/math/fibonacci)
212213
* `B` [Jump Game](src/algorithms/uncategorized/jump-game)
@@ -278,6 +279,8 @@ rm -rf ./node_modules
278279
npm i
279280
```
280281

282+
Also make sure that you're using a correct Node version (`>=14.16.0`). If you're using [nvm](https://github.com/nvm-sh/nvm) for Node version management you may run `nvm use` from the root folder of the project and the correct version will be picked up.
283+
281284
**Playground**
282285

283286
You may play with data-structures and algorithms in `./src/playground/playground.js` file and write

‎src/algorithms/sets/maximum-subarray/README.md

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Maximum subarray problem
22

3-
The maximum subarray problem is the task of finding the contiguous
4-
subarray within a one-dimensional array, `a[1...n]`, of numbers
3+
The maximum subarray problem is the task of finding the contiguous
4+
subarray within a one-dimensional array, `a[1...n]`, of numbers
55
which has the largest sum, where,
66

77
![Maximum subarray](https://wikimedia.org/api/rest_v1/media/math/render/svg/e8960f093107b71b21827e726e2bad8b023779b2)
@@ -10,11 +10,17 @@ which has the largest sum, where,
1010

1111
## Example
1212

13-
The list usually contains both positive and negative numbers along
14-
with `0`. For example, for the array of
15-
values `−2, 1, −3, 4, −1, 2, 1, −5, 4` the contiguous subarray
13+
The list usually contains both positive and negative numbers along
14+
with `0`. For example, for the array of
15+
values `−2, 1, −3, 4, −1, 2, 1, −5, 4` the contiguous subarray
1616
with the largest sum is `4, −1, 2, 1`, with sum `6`.
1717

18+
## Solutions
19+
20+
- Brute Force solution `O(n^2)`: [bfMaximumSubarray.js](./bfMaximumSubarray.js)
21+
- Divide and Conquer solution `O(n^2)`: [dcMaximumSubarraySum.js](./dcMaximumSubarraySum.js)
22+
- Dynamic Programming solution `O(n)`: [dpMaximumSubarray.js](./dpMaximumSubarray.js)
23+
1824
## References
1925

2026
- [Wikipedia](https://en.wikipedia.org/wiki/Maximum_subarray_problem)

‎src/algorithms/sets/maximum-subarray/__test__/bfMaximumSubarray.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import bfMaximumSubarray from '../bfMaximumSubarray';
22

33
describe('bfMaximumSubarray', () => {
4-
it('should find maximum subarray using brute force algorithm', () => {
4+
it('should find maximum subarray using the brute force algorithm', () => {
55
expect(bfMaximumSubarray([])).toEqual([]);
66
expect(bfMaximumSubarray([0, 0])).toEqual([0]);
77
expect(bfMaximumSubarray([0, 0, 1])).toEqual([0, 0, 1]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import dcMaximumSubarray from '../dcMaximumSubarraySum';
2+
3+
describe('dcMaximumSubarraySum', () => {
4+
it('should find maximum subarray sum using the divide and conquer algorithm', () => {
5+
expect(dcMaximumSubarray([])).toEqual(-Infinity);
6+
expect(dcMaximumSubarray([0, 0])).toEqual(0);
7+
expect(dcMaximumSubarray([0, 0, 1])).toEqual(1);
8+
expect(dcMaximumSubarray([0, 0, 1, 2])).toEqual(3);
9+
expect(dcMaximumSubarray([0, 0, -1, 2])).toEqual(2);
10+
expect(dcMaximumSubarray([-1, -2, -3, -4, -5])).toEqual(-1);
11+
expect(dcMaximumSubarray([1, 2, 3, 2, 3, 4, 5])).toEqual(20);
12+
expect(dcMaximumSubarray([-2, 1, -3, 4, -1, 2, 1, -5, 4])).toEqual(6);
13+
expect(dcMaximumSubarray([-2, -3, 4, -1, -2, 1, 5, -3])).toEqual(7);
14+
expect(dcMaximumSubarray([1, -3, 2, -5, 7, 6, -1, 4, 11, -23])).toEqual(27);
15+
});
16+
});

‎src/algorithms/sets/maximum-subarray/__test__/dpMaximumSubarray.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import dpMaximumSubarray from '../dpMaximumSubarray';
22

33
describe('dpMaximumSubarray', () => {
4-
it('should find maximum subarray using dynamic programming algorithm', () => {
4+
it('should find maximum subarray using the dynamic programming algorithm', () => {
55
expect(dpMaximumSubarray([])).toEqual([]);
66
expect(dpMaximumSubarray([0, 0])).toEqual([0]);
77
expect(dpMaximumSubarray([0, 0, 1])).toEqual([0, 0, 1]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Divide and Conquer solution.
3+
* Complexity: O(n^2) in case if no memoization applied
4+
*
5+
* @param {Number[]} inputArray
6+
* @return {Number[]}
7+
*/
8+
export default function dcMaximumSubarraySum(inputArray) {
9+
/**
10+
* We are going through the inputArray array and for each element we have two options:
11+
* - to pick
12+
* - not to pick
13+
*
14+
* Also keep in mind, that the maximum sub-array must be contiguous. It means if we picked
15+
* the element, we need to continue picking the next elements or stop counting the max sum.
16+
*
17+
* @param {number} elementIndex - the index of the element we're deciding to pick or not
18+
* @param {boolean} mustPick - to pick or not to pick the element
19+
* @returns {number} - maximum subarray sum that we'll get
20+
*/
21+
function solveRecursively(elementIndex, mustPick) {
22+
if (elementIndex >= inputArray.length) {
23+
return mustPick ? 0 : -Infinity;
24+
}
25+
return Math.max(
26+
// Option #1: Pick the current element, and continue picking next one.
27+
inputArray[elementIndex] + solveRecursively(elementIndex + 1, true),
28+
// Option #2: Don't pick the current element.
29+
mustPick ? 0 : solveRecursively(elementIndex + 1, false),
30+
);
31+
}
32+
return solveRecursively(0, false);
33+
}

0 commit comments

Comments
 (0)
Please sign in to comment.