Skip to content

Commit 5935b95

Browse files
committed
feat(book/array): add max subarray questions and solution
1 parent 57960e2 commit 5935b95

9 files changed

+129
-61
lines changed

book/D-interview-questions-solutions.asc

+25-15
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,42 @@
66
=== Solutions for Array Questions
77
(((Interview Questions Solutions, Arrays)))
88

9-
==== Rotate Left
10-
include::content/part02/array.asc[tag=array-q-rotate-left]
9+
==== Max Subarray [[array-q-max-subarray]]
10+
include::content/part02/array.asc[tag=array-q-max-subarray]
1111

12-
We are asked to rotate an array multiple times (`k`).
12+
The first step, is making sure we understand the problem well. Let's do a basic examples:
1313

14-
One brute force solution, would be removing the first element and appending it to the end `k` times:
14+
----
15+
A = [-5, 6, 9, -8]
16+
B = [-1, 6, -3, 8]
17+
----
18+
19+
What's the subarrays with the maximum sum? For A, it will be `[6, 9]` and for B it will be `[6, -3, 8]`.
20+
21+
One intution could be to generate all possible subarrays, add them up and then pick the max number.
1522

1623
[source, javascript]
1724
----
18-
include::interview-questions/rotate-array-left.js[tag=bruteForce]
25+
include::interview-questions/max-subarray.js[tag=maxSubArrayBrute1]
1926
----
2027

21-
However, what would happen if the array is huge (millions of elements)?
22-
How efficient will be if `k` number is large (thousands)?
23-
24-
When k is bigger than the array, it will loop back over and over again. We can avoid extra computation by calculating the final place using modulus.
28+
This is a simple to understand however not very efficient. The runtime is `O(n^3)`.
2529

26-
Here's the final solution:
30+
If you noticed we adding up the numbers from `i` to `j` on each cycle. But, we can optimize this. We can keep a local variable and add the new number to it. That way we don't have to revisit previous numebers again.
2731

2832
[source, javascript]
2933
----
30-
include::interview-questions/rotate-array-left.js[tag=description]
31-
include::interview-questions/rotate-array-left.js[tag=solution]
34+
include::interview-questions/max-subarray.js[tag=maxSubArrayBrute2]
3235
----
3336

34-
It runs on `O(n^2)` while the brute force solution was doing `O(n^2 * k)`.
37+
The runtime is much better: `O(n)`. Can we still do better?
38+
39+
We can use a greedy approach, where do one pass through the array. We only add the numbers if their sum is larger than just taking the current element.
40+
41+
[source, javascript]
42+
----
43+
include::interview-questions/max-subarray.js[tag=description]
44+
include::interview-questions/max-subarray.js[tag=solution]
45+
----
3546

36-
==== Sum
37-
include::content/part02/array.asc[tag=array-sum]
47+
The runtime is `O(n)`! and a space complexity of `O(1)`.

book/content/part02/array.asc

+8-25
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ ifndef::imagesdir[]
44
endif::[]
55

66
[[array]]
7-
=== Array
7+
=== Array [[array-chap]]
88
(((Array)))
99
(((Data Structures, Linear, Array)))
1010
Arrays are one of the most used data structures. You probably have used it a lot but are you aware of the runtimes of `splice`, `shift`, `indexOf` and other operations? In this chapter, we are going deeper into the most common operations and their runtimes.
@@ -279,35 +279,18 @@ To sum up, the time complexity of an array is:
279279
==== Interview Questions
280280
(((Interview Questions, Arrays)))
281281

282-
// tag::array-q-rotate-left[]
283-
1) Implement an efficient algorithm that rotate an array `a` an `k` number of times.
282+
===== Max Subarray
283+
// tag::array-q-max-subarray[]
284+
Given an array of integers, find the maximum sum of consecutive elements (subarray).
285+
// end::array-q-max-subarray[]
284286

285287
[source, javascript]
286288
----
287-
include::../../interview-questions/rotate-array-left.js[tag=description]
289+
include::../../interview-questions/max-subarray.js[tag=description]
288290
// write you code here
289291
}
290292
----
291-
// end::array-q-rotate-left[]
292293

293-
// tag::array-sum[]
294-
2) Implement an algorithm that takes two arrays of numbers and return a new array with the sum.
294+
_Solution: <<array-q-max-subarray>>_
295295

296-
[source, javascript]
297-
----
298-
/**
299-
* Return the sum of two arrays as a new array.
300-
*
301-
* @example
302-
* sum([1,2,3], [1,1,1]); // [2,3,4]
303-
* sum([1], [9,9,9]); // [1,0,0,0]
304-
*
305-
* @param {number[]} a - Array of numbers.
306-
* @param {number[]} b - Array of numbers.
307-
* @returns {number[]} the sum array.
308-
*/
309-
function sum(a, b) {
310-
// write you code and test with examples
311-
}
312-
----
313-
// end::array-sum[]
296+
// https://leetcode.com/problemset/algorithms/?topicSlugs=array

book/interview-questions/max-subarray.data.js

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// tag::description[]
2+
/**
3+
* Find the maximun sum of contiguous elements in an array.
4+
* @examples
5+
* maxSubArray([1, -3, 10, -5]); // => 10
6+
* maxSubArray([-3,4,-1,2,1,-5]); // => 6
7+
* @param {number[]} a - Array
8+
*/
9+
function maxSubArray(a) {
10+
// end::description[]
11+
// tag::solution[]
12+
let max = -Infinity;
13+
let local = 0;
14+
15+
a.forEach((n) => {
16+
local = Math.max(n, local + n);
17+
max = Math.max(max, local);
18+
});
19+
20+
return max;
21+
}
22+
// end::solution[]
23+
24+
// tag::maxSubArrayBrute1[]
25+
function maxSubArrayBrute1(nums) {
26+
let max = -Infinity;
27+
28+
for (let i = 0; i < nums.length; i++) { // O(n^3)
29+
for (let j = i + 1; j <= nums.length; j++) { // O(n^2)
30+
const sum = nums.slice(i, j).reduce((a, n) => n + a, 0); // O(n)
31+
max = Math.max(max, sum); // O(1)
32+
}
33+
}
34+
35+
return max;
36+
}
37+
// end::maxSubArrayBrute1[]
38+
39+
// tag::maxSubArrayBrute2[]
40+
function maxSubArrayBrute2(nums) {
41+
let max = -Infinity;
42+
43+
for (let i = 0; i < nums.length; i++) { // O(n) * O(n)
44+
let local = 0;
45+
for (let j = i; j < nums.length; j++) { // O(n)
46+
local += nums[j];
47+
max = Math.max(max, local);
48+
}
49+
}
50+
return max;
51+
}
52+
// end::maxSubArrayBrute2[]
53+
54+
module.exports = { maxSubArrayBrute1, maxSubArrayBrute2, maxSubArray };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const { maxSubArray, maxSubArrayBrute1, maxSubArrayBrute2 } = require('./max-subarray');
2+
const largeArray = require('./max-subarray.data');
3+
4+
describe('Max Subarray Sum', () => {
5+
[maxSubArray, maxSubArrayBrute1, maxSubArrayBrute2].forEach((fn) => {
6+
describe(`with ${fn.name}`, () => {
7+
it('should work with small arrays', () => {
8+
expect(fn([-2, 1, -3, 4, -1, 2, 1, -5, 4])).toEqual(6);
9+
});
10+
11+
it('should work with large arrays', () => {
12+
expect(fn(largeArray)).toEqual(4853);
13+
});
14+
});
15+
});
16+
});

book/interview-questions/rotate-array-left.spec.js

-19
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const { rotateLeft, rotateLeftBruteForce } = require('./rotate-array-left');
2+
3+
const largeArray = Array(1e6).fill(1).map((t) => t * Math.random());
4+
5+
[rotateLeft, rotateLeftBruteForce].forEach((fn) => {
6+
xdescribe(`Rotate Left ${fn.name}`, () => {
7+
describe('when data is small', () => {
8+
it('should work with 1', () => {
9+
expect(fn([1, 2, 3], 1)).toEqual([2, 3, 1]);
10+
});
11+
12+
it('should work with 4', () => {
13+
expect(fn([1, 2, 3, 4, 5], 4)).toEqual([5, 1, 2, 3, 4]);
14+
});
15+
});
16+
17+
xdescribe('when data is large', () => {
18+
it('should work at scale', () => {
19+
expect(fn(largeArray, 75863)).toEqual(largeArray);
20+
});
21+
});
22+
});
23+
});

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"src/**/*.js"
1414
],
1515
"scripts": {
16-
"test": "jest",
17-
"watch": "jest --watch --coverage",
16+
"test": "jest --verbose",
17+
"watch": "jest --watch --verbose --coverage",
1818
"coverage": "jest --coverage && open coverage/lcov-report/index.html",
1919
"coverage:win": "jest --coverage && cmd.exe /C start coverage/lcov-report/index.html",
2020
"lint": "npx eslint --fix --format codeframe src/",

0 commit comments

Comments
 (0)