Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5935b95

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

File tree

9 files changed

+129
-61
lines changed

9 files changed

+129
-61
lines changed

‎book/D-interview-questions-solutions.asc

Lines changed: 25 additions & 15 deletions
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

Lines changed: 8 additions & 25 deletions
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

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 54 additions & 0 deletions
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 };
Lines changed: 16 additions & 0 deletions
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

Lines changed: 0 additions & 19 deletions
This file was deleted.
File renamed without changes.
Lines changed: 23 additions & 0 deletions
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

Lines changed: 2 additions & 2 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /