mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-12-25 14:36:10 +08:00
Add a Divide and Conquer version of the MaxSubArray problem.
This commit is contained in:
parent
819f38f792
commit
82f0b5edf0
@ -207,6 +207,7 @@ algorithm is an abstraction higher than a computer program.
|
|||||||
* `B` [Best Time To Buy Sell Stocks](src/algorithms/uncategorized/best-time-to-buy-sell-stocks) - divide and conquer and one-pass examples
|
* `B` [Best Time To Buy Sell Stocks](src/algorithms/uncategorized/best-time-to-buy-sell-stocks) - divide and conquer and one-pass examples
|
||||||
* `A` [Permutations](src/algorithms/sets/permutations) (with and without repetitions)
|
* `A` [Permutations](src/algorithms/sets/permutations) (with and without repetitions)
|
||||||
* `A` [Combinations](src/algorithms/sets/combinations) (with and without repetitions)
|
* `A` [Combinations](src/algorithms/sets/combinations) (with and without repetitions)
|
||||||
|
* `A` [Maximum Subarray](src/algorithms/sets/maximum-subarray)
|
||||||
* **Dynamic Programming** - build up a solution using previously found sub-solutions
|
* **Dynamic Programming** - build up a solution using previously found sub-solutions
|
||||||
* `B` [Fibonacci Number](src/algorithms/math/fibonacci)
|
* `B` [Fibonacci Number](src/algorithms/math/fibonacci)
|
||||||
* `B` [Jump Game](src/algorithms/uncategorized/jump-game)
|
* `B` [Jump Game](src/algorithms/uncategorized/jump-game)
|
||||||
@ -278,6 +279,8 @@ rm -rf ./node_modules
|
|||||||
npm i
|
npm i
|
||||||
```
|
```
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
**Playground**
|
**Playground**
|
||||||
|
|
||||||
You may play with data-structures and algorithms in `./src/playground/playground.js` file and write
|
You may play with data-structures and algorithms in `./src/playground/playground.js` file and write
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Maximum subarray problem
|
# Maximum subarray problem
|
||||||
|
|
||||||
The maximum subarray problem is the task of finding the contiguous
|
The maximum subarray problem is the task of finding the contiguous
|
||||||
subarray within a one-dimensional array, `a[1...n]`, of numbers
|
subarray within a one-dimensional array, `a[1...n]`, of numbers
|
||||||
which has the largest sum, where,
|
which has the largest sum, where,
|
||||||
|
|
||||||
![Maximum subarray](https://wikimedia.org/api/rest_v1/media/math/render/svg/e8960f093107b71b21827e726e2bad8b023779b2)
|
![Maximum subarray](https://wikimedia.org/api/rest_v1/media/math/render/svg/e8960f093107b71b21827e726e2bad8b023779b2)
|
||||||
@ -10,11 +10,17 @@ which has the largest sum, where,
|
|||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
The list usually contains both positive and negative numbers along
|
The list usually contains both positive and negative numbers along
|
||||||
with `0`. For example, for the array of
|
with `0`. For example, for the array of
|
||||||
values `−2, 1, −3, 4, −1, 2, 1, −5, 4` the contiguous subarray
|
values `−2, 1, −3, 4, −1, 2, 1, −5, 4` the contiguous subarray
|
||||||
with the largest sum is `4, −1, 2, 1`, with sum `6`.
|
with the largest sum is `4, −1, 2, 1`, with sum `6`.
|
||||||
|
|
||||||
|
## Solutions
|
||||||
|
|
||||||
|
- Brute Force solution `O(n^2)`: [bfMaximumSubarray.js](./bfMaximumSubarray.js)
|
||||||
|
- Divide and Conquer solution `O(n^2)`: [dcMaximumSubarraySum.js](./dcMaximumSubarraySum.js)
|
||||||
|
- Dynamic Programming solution `O(n)`: [dpMaximumSubarray.js](./dpMaximumSubarray.js)
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- [Wikipedia](https://en.wikipedia.org/wiki/Maximum_subarray_problem)
|
- [Wikipedia](https://en.wikipedia.org/wiki/Maximum_subarray_problem)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import bfMaximumSubarray from '../bfMaximumSubarray';
|
import bfMaximumSubarray from '../bfMaximumSubarray';
|
||||||
|
|
||||||
describe('bfMaximumSubarray', () => {
|
describe('bfMaximumSubarray', () => {
|
||||||
it('should find maximum subarray using brute force algorithm', () => {
|
it('should find maximum subarray using the brute force algorithm', () => {
|
||||||
expect(bfMaximumSubarray([])).toEqual([]);
|
expect(bfMaximumSubarray([])).toEqual([]);
|
||||||
expect(bfMaximumSubarray([0, 0])).toEqual([0]);
|
expect(bfMaximumSubarray([0, 0])).toEqual([0]);
|
||||||
expect(bfMaximumSubarray([0, 0, 1])).toEqual([0, 0, 1]);
|
expect(bfMaximumSubarray([0, 0, 1])).toEqual([0, 0, 1]);
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
import dcMaximumSubarray from '../dcMaximumSubarraySum';
|
||||||
|
|
||||||
|
describe('dcMaximumSubarraySum', () => {
|
||||||
|
it('should find maximum subarray sum using the divide and conquer algorithm', () => {
|
||||||
|
expect(dcMaximumSubarray([])).toEqual(-Infinity);
|
||||||
|
expect(dcMaximumSubarray([0, 0])).toEqual(0);
|
||||||
|
expect(dcMaximumSubarray([0, 0, 1])).toEqual(1);
|
||||||
|
expect(dcMaximumSubarray([0, 0, 1, 2])).toEqual(3);
|
||||||
|
expect(dcMaximumSubarray([0, 0, -1, 2])).toEqual(2);
|
||||||
|
expect(dcMaximumSubarray([-1, -2, -3, -4, -5])).toEqual(-1);
|
||||||
|
expect(dcMaximumSubarray([1, 2, 3, 2, 3, 4, 5])).toEqual(20);
|
||||||
|
expect(dcMaximumSubarray([-2, 1, -3, 4, -1, 2, 1, -5, 4])).toEqual(6);
|
||||||
|
expect(dcMaximumSubarray([-2, -3, 4, -1, -2, 1, 5, -3])).toEqual(7);
|
||||||
|
expect(dcMaximumSubarray([1, -3, 2, -5, 7, 6, -1, 4, 11, -23])).toEqual(27);
|
||||||
|
});
|
||||||
|
});
|
@ -1,7 +1,7 @@
|
|||||||
import dpMaximumSubarray from '../dpMaximumSubarray';
|
import dpMaximumSubarray from '../dpMaximumSubarray';
|
||||||
|
|
||||||
describe('dpMaximumSubarray', () => {
|
describe('dpMaximumSubarray', () => {
|
||||||
it('should find maximum subarray using dynamic programming algorithm', () => {
|
it('should find maximum subarray using the dynamic programming algorithm', () => {
|
||||||
expect(dpMaximumSubarray([])).toEqual([]);
|
expect(dpMaximumSubarray([])).toEqual([]);
|
||||||
expect(dpMaximumSubarray([0, 0])).toEqual([0]);
|
expect(dpMaximumSubarray([0, 0])).toEqual([0]);
|
||||||
expect(dpMaximumSubarray([0, 0, 1])).toEqual([0, 0, 1]);
|
expect(dpMaximumSubarray([0, 0, 1])).toEqual([0, 0, 1]);
|
||||||
|
33
src/algorithms/sets/maximum-subarray/dcMaximumSubarraySum.js
Normal file
33
src/algorithms/sets/maximum-subarray/dcMaximumSubarraySum.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Divide and Conquer solution.
|
||||||
|
* Complexity: O(n^2) in case if no memoization applied
|
||||||
|
*
|
||||||
|
* @param {Number[]} inputArray
|
||||||
|
* @return {Number[]}
|
||||||
|
*/
|
||||||
|
export default function dcMaximumSubarraySum(inputArray) {
|
||||||
|
/**
|
||||||
|
* We are going through the inputArray array and for each element we have two options:
|
||||||
|
* - to pick
|
||||||
|
* - not to pick
|
||||||
|
*
|
||||||
|
* Also keep in mind, that the maximum sub-array must be contiguous. It means if we picked
|
||||||
|
* the element, we need to continue picking the next elements or stop counting the max sum.
|
||||||
|
*
|
||||||
|
* @param {number} elementIndex - the index of the element we're deciding to pick or not
|
||||||
|
* @param {boolean} mustPick - to pick or not to pick the element
|
||||||
|
* @returns {number} - maximum subarray sum that we'll get
|
||||||
|
*/
|
||||||
|
function solveRecursively(elementIndex, mustPick) {
|
||||||
|
if (elementIndex >= inputArray.length) {
|
||||||
|
return mustPick ? 0 : -Infinity;
|
||||||
|
}
|
||||||
|
return Math.max(
|
||||||
|
// Option #1: Pick the current element, and continue picking next one.
|
||||||
|
inputArray[elementIndex] + solveRecursively(elementIndex + 1, true),
|
||||||
|
// Option #2: Don't pick the current element.
|
||||||
|
mustPick ? 0 : solveRecursively(elementIndex + 1, false),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return solveRecursively(0, false);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user