Skip to content

Commit 9b356d9

Browse files
Merge pull request #67 from amejiarosario/feat/add-exercises-solutions
Feat/add exercises solutions
2 parents 3901188 + dbdef21 commit 9b356d9

25 files changed

+325
-95
lines changed

.vscode/settings.json

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
{
2+
"peacock.color": "#f9e64f",
23
"workbench.colorCustomizations": {
4+
"activityBar.activeBackground": "#fbed80",
5+
"activityBar.activeBorder": "#06b9a5",
36
"activityBar.background": "#fbed80",
47
"activityBar.foreground": "#15202b",
58
"activityBar.inactiveForeground": "#15202b99",
69
"activityBarBadge.background": "#06b9a5",
710
"activityBarBadge.foreground": "#15202b",
8-
"titleBar.activeBackground": "#f9e64f",
9-
"titleBar.inactiveBackground": "#f9e64f99",
10-
"titleBar.activeForeground": "#15202b",
11-
"titleBar.inactiveForeground": "#15202b99",
1211
"statusBar.background": "#f9e64f",
12+
"statusBar.foreground": "#15202b",
1313
"statusBarItem.hoverBackground": "#f7df1e",
14-
"statusBar.foreground": "#15202b"
14+
"titleBar.activeBackground": "#f9e64f",
15+
"titleBar.activeForeground": "#15202b",
16+
"titleBar.inactiveBackground": "#f9e64f99",
17+
"titleBar.inactiveForeground": "#15202b99"
1518
},
16-
"peacock.color": "#f9e64f"
19+
"peacock.remoteColor": "#f9e64f"
1720
}

book/A-time-complexity-cheatsheet.asc

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
[appendix]
2-
[[a-time-complexity-cheatsheet]]
3-
== Cheatsheet
2+
== Cheatsheet [[a-time-complexity-cheatsheet]]
43

54
This section summerize what we are going to cover in the rest of this book.
65

book/B-self-balancing-binary-search-trees.asc

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
[appendix]
2-
[[b-self-balancing-binary-search-trees]]
3-
== Self-balancing Binary Search Trees
2+
== Self-balancing Binary Search Trees [[b-self-balancing-binary-search-trees]]
43

54
Binary Search Trees (BST) are an excellent data structure to find elements very fast _O(log n)_.
65
However, when the BST branches have different branch sizes, then the performance suffers.
@@ -28,8 +27,7 @@ As you might notice, we balanced the tree in the example by doing a rotation.
2827
To be more specific we rotated node `1` to the left to balance the tree.
2928
Let's examine all the possible rotation we can do to balance a tree.
3029

31-
[[tree-rotations]]
32-
=== Tree Rotations
30+
=== Tree Rotations [[tree-rotations]]
3331
(((Tree Rotations)))
3432
We can do single rotations left and right and also we can do double rotations.
3533
Let's go one by one.

book/C-AVL-tree.asc

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
[appendix]
2-
[[c-avl-tree]]
3-
== AVL Tree
2+
== AVL Tree [[c-avl-tree]]
43
(((AVL Tree)))
54
(((Tree, AVL)))
65
AVL Tree is named after their inventors (**A**delson-**V**elsky and **L**andis).
@@ -60,4 +59,4 @@ include::../src/data-structures/trees/avl-tree.js[tag=balance]
6059
The first thing we do is to see if one subtree is longer than the other.
6160
If so, then we check the children balance to determine if need a single or double rotation and in which direction.
6261

63-
You can review <<b-self-balancing-binary-search-trees#tree-rotations>> in case you want a refresher.
62+
You can review <<tree-rotations>> in case you want a refresher.
+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
[appendix]
2+
[[d-interview-questions-solutions]]
3+
== Interview Questions Solutions
4+
(((Interview Questions Solutions)))
5+
6+
=== Solutions for Array Questions
7+
(((Interview Questions Solutions, Arrays)))
8+
9+
:leveloffset: -1
10+
11+
[#array-q-max-subarray]
12+
include::content/part02/array.asc[tag=array-q-max-subarray]
13+
14+
The first step is making sure we understand the problem well. Let's do basic examples:
15+
16+
----
17+
A = [-5, 6, 9, -8]
18+
B = [-1, 6, -3, 8]
19+
----
20+
21+
What's the subarray with the maximum sum? For A, it will be `[6, 9]` and for B, it will be `[6, -3, 8]`.
22+
23+
We could generate all possible subarrays, add them up, and then pick the max number.
24+
25+
[source, javascript]
26+
----
27+
include::interview-questions/max-subarray.js[tag=maxSubArrayBrute1]
28+
----
29+
30+
This code is simple to understand; however, not very efficient. The runtime is `O(n^3)`.
31+
32+
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 numbers.
33+
34+
[source, javascript]
35+
----
36+
include::interview-questions/max-subarray.js[tag=maxSubArrayBrute2]
37+
----
38+
39+
The runtime is much better: `O(n)`. Can we still do better?
40+
41+
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.
42+
43+
[source, javascript]
44+
----
45+
include::interview-questions/max-subarray.js[tag=description]
46+
include::interview-questions/max-subarray.js[tag=solution]
47+
----
48+
49+
The runtime is `O(n)` and a space complexity of `O(1)`.
50+
51+
52+
53+
54+
[#array-q-buy-sell-stock]
55+
include::content/part02/array.asc[tag=array-q-buy-sell-stock]
56+
57+
There are multiple examples that we can simulate: bear markets (when prices are going down), bullish markets (when prices are going up), and zig-zag markets (when prices are going up and down).
58+
59+
[source, javascript]
60+
----
61+
// zig-zag market
62+
maxProfit([5, 10, 5, 10]); // => 5
63+
// bullish market
64+
maxProfit([1, 2, 3]); // => 2
65+
// bearish market
66+
maxProfit([3, 2, 1]); // => 0
67+
----
68+
69+
During the bearish markets, the profit will always be 0. Since if you buy, we are only going to lose.
70+
71+
We can do a brute force solution doing all combinations:
72+
73+
[source, javascript]
74+
----
75+
include::interview-questions/buy-sell-stock.js[tag=maxProfitBrute1]
76+
----
77+
78+
The runtime for this solution is `O(n^2)`.
79+
80+
A better solution is to eliminate the 2nd for loop and only do one pass.
81+
82+
Algorithm:
83+
84+
- Do one pass through all the prices
85+
- Keep track of the minimum price seen so far.
86+
- calculate `profit = currentPrice - minPriceSoFar`
87+
- Keep track of the maximun profit seen so far.
88+
- Return maxProfit.
89+
90+
[source, javascript]
91+
----
92+
include::interview-questions/buy-sell-stock.js[tag=description]
93+
include::interview-questions/buy-sell-stock.js[tag=solution]
94+
----
95+
96+
The runtime is `O(n)` and a space complexity of `O(1)`.

book/ch02-git-basics-chapter.asc

-35
This file was deleted.

book/config

book/content/part02/array-vs-list-vs-queue-vs-stack.asc

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ In this part of the book, we explored the most used linear data structures such
3131
|===
3232
.2+.^s| Data Structure 2+^s| Searching By 3+^s| Inserting at the 3+^s| Deleting from .2+.^s| Space
3333
^|_Index/Key_ ^|_Value_ ^|_beginning_ ^|_middle_ ^|_end_ ^|_beginning_ ^|_middle_ ^|_end_
34-
| <<part02-linear-data-structures#array>> ^|O(1) ^|O(n) ^|O(n) ^|O(n) ^|O(1) ^|O(n) ^|O(n) ^|O(1) ^|O(n)
34+
| <<array-chap>> ^|O(1) ^|O(n) ^|O(n) ^|O(n) ^|O(1) ^|O(n) ^|O(n) ^|O(1) ^|O(n)
3535
| <<part02-linear-data-structures#singly-linked-list>> ^|O(n) ^|O(n) ^|O(1) ^|O(n) ^|*O(n)* ^|O(1) ^|O(n) ^|*O(n)* ^|O(n)
3636
| <<part02-linear-data-structures#doubly-linked-list>> ^|O(n) ^|O(n) ^|O(1) ^|O(n) ^|*O(1)* ^|O(1) ^|O(n) ^|*O(1)* ^|O(n)
3737
| <<part02-linear-data-structures#stack>> ^|- ^|- ^|- ^|- ^|O(1) ^|- ^|- ^|O(1) ^|O(n)

book/content/part02/array.asc

+24-32
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.
@@ -17,7 +17,8 @@ TIP: Strings are a collection of Unicode characters and most of the array concep
1717

1818
.Fixed vs. Dynamic Size Arrays
1919
****
20-
Some programming languages have fixed size arrays like Java and C++. Fixed size arrays might be a hassle when your collection gets full, and you have to create a new one with a bigger size. For that, those programming languages also have built-in dynamic arrays: we have `vector` in C++ and `ArrayList` in Java. Dynamic programming languages like JavaScript, Ruby, and Python use dynamic arrays by default.
20+
Some programming languages have fixed size arrays like Java and {cpp}.
21+
Fixed size arrays might be a hassle when your collection gets full, and you have to create a new one with a bigger size. For that, those programming languages also have built-in dynamic arrays: we have `vector` in {cpp} and `ArrayList` in Java. Dynamic programming languages like JavaScript, Ruby, and Python use dynamic arrays by default.
2122
****
2223

2324
Arrays look like this:
@@ -275,46 +276,37 @@ To sum up, the time complexity of an array is:
275276
|===
276277
//end::table
277278

278-
==== Array Exercises
279+
==== Interview Questions
280+
(((Interview Questions, Arrays)))
279281

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

282288
[source, javascript]
283289
----
284-
/**
285-
* Rotate an array left by k number of times.
286-
*
287-
* @example
288-
* rotateLeft([1,2,3], 1); // [2,3,1]
289-
* rotateLeft([1,2,3,4,5], 4); // [5,1,2,3,4]
290-
*
291-
* rotateLeft(Array(1e6).fill(1), 1e4); // <scale testing>
292-
*
293-
* @param a - The array
294-
* @param k - The number of times the array is rotated
295-
*/
296-
function rotateLeft(a, k) {
297-
// write you code and test with examples
290+
include::../../interview-questions/max-subarray.js[tag=description]
291+
// write you code here
298292
}
299293
----
300294

295+
_Solution: <<array-q-max-subarray>>_
296+
297+
// tag::array-q-buy-sell-stock[]
298+
===== Best Time to Buy and Sell an Stock
301299

302-
2) Implement an algorithm that takes two arrays of numbers and return a new array with the sum.
300+
You are given an array of integers. Each value represents the closing value of the stock on that day. You are only given one chance to buy and then sell. What's the maximun profit you can obtain? (Note: you have to buy first and then sell)
301+
// end::array-q-buy-sell-stock[]
303302

304303
[source, javascript]
305304
----
306-
/**
307-
* Return the sum of two arrays as a new array.
308-
*
309-
* @example
310-
* sum([1,2,3], [1,1,1]); // [2,3,4]
311-
* sum([1], [9,9,9]); // [1,0,0,0]
312-
*
313-
* @param {number[]} a - Array of numbers.
314-
* @param {number[]} b - Array of numbers.
315-
* @returns {number[]} the sum array.
316-
*/
317-
function sum(a, b) {
318-
// write you code and test with examples
305+
include::../../interview-questions/buy-sell-stock.js[tag=description]
306+
// write you code here
319307
}
320308
----
309+
310+
_Solution: <<array-q-buy-sell-stock>>_
311+
312+
// https://leetcode.com/problemset/algorithms/?topicSlugs=array

book/content/part03/map.asc

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ In short, you set `key`/`value` pair and then you can get the `value` using the
2424
The attractive part of Maps is that they are very performant usually *O(1)* or *O(log n)* depending on the implementation. We can implement the maps using two different underlying data structures:
2525

2626
* *HashMap*: it’s a map implementation using an *array* and a *hash function*. The job of the hash function is to convert the `key` into an index that maps to the `value`. Optimized HashMap can have an average runtime of *O(1)*.
27-
* *TreeMap*: it’s a map implementation that uses a self-balanced Binary Search Tree (like <<c-avl-tree#>>). The BST nodes store the key, and the value and nodes are sorted by key guaranteeing an *O(log n)* look up.
27+
* *TreeMap*: it’s a map implementation that uses a self-balanced Binary Search Tree (like <<c-avl-tree>>). The BST nodes store the key, and the value and nodes are sorted by key guaranteeing an *O(log n)* look up.
2828

2929
<<<
3030
include::hashmap.asc[]

book/content/part03/time-complexity-graph-data-structures.asc

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ In this section, we learned about Graphs applications, properties and how we can
1414
.2+.^s| Data Structure 2+^s| Searching By .2+^.^s| Insert .2+^.^s| Delete .2+^.^s| Space Complexity
1515
^|_Index/Key_ ^|_Value_
1616
| <<part03-graph-data-structures#bst, BST (unbalanced)>> ^|- ^|O(n) ^|O(n) ^|O(n) ^|O(n)
17-
| <<b-self-balancing-binary-search-trees#, BST (balanced)>> ^|- ^|O(log n) ^|O(log n) ^|O(log n) ^|O(n)
17+
| <<b-self-balancing-binary-search-trees, BST (balanced)>> ^|- ^|O(log n) ^|O(log n) ^|O(log n) ^|O(n)
1818
| Hash Map (naïve) ^|O(n) ^|O(n) ^|O(n) ^|O(n) ^|O(n)
1919
| <<part03-graph-data-structures#hashmap, HashMap>> (optimized) ^|O(1) ^|O(n) ^|O(1)* ^|O(1) ^|O(n)
2020
| <<part03-graph-data-structures#treemap, TreeMap>> (Red-Black Tree) ^|O(log n) ^|O(n) ^|O(log n) ^|O(log n) ^|O(n)

book/content/preface.asc

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
=== What is in this book?
55

6-
_{doctitle}_ is a book that can be read from cover to cover, where each section builds on top of the previous one. Also, it can be used as a reference manual where developers can refresh specific topics before an interview or look for ideas to solve a problem optimally. (Check out the <<a-time-complexity-cheatsheet#,Time Complexity Cheatsheet>> and <<index#, topical index>>)
6+
_{doctitle}_ is a book that can be read from cover to cover, where each section builds on top of the previous one. Also, it can be used as a reference manual where developers can refresh specific topics before an interview or look for ideas to solve a problem optimally. (Check out the <<a-time-complexity-cheatsheet,Time Complexity Cheatsheet>> and <<index, topical index>>)
77

88
This publication is designed to be concise, intending to serve software developers looking to get a firm conceptual understanding of data structures in a quick yet in-depth fashion. After reading this book, the reader should have a fundamental knowledge of algorithms, including when and where to apply it, what are the trade-offs of using one data structure over the other. The reader will then be able to make intelligent decisions about algorithms and data structures in their projects.
99

@@ -82,4 +82,4 @@ Measurement is the first step that leads to control and eventually to improvemen
8282

8383
Your feedback is very welcome and valuable. Let us know what your thoughts about this book — what you like or ideas to make it better.
8484

85-
To send us feedback, e-mail us at [email protected], send a tweet to https://twitter.com/iAmAdrianMejia[@iAmAdrianMejia], or using the hash tags `#dsaJS`, `#javascript` and `#algorithms`.
85+
To send us feedback, e-mail us at [email protected], send a tweet to https://twitter.com/iAmAdrianMejia[@iAmAdrianMejia], or using the hash tag `#dsaJS`.

book/index.asc

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
[index]
2-
[[index]]
3-
== Index
2+
== Index [[index]]
43

54
ifndef::backend-pdf[Topical index only available on the PDF version.]
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// tag::description[]
2+
/**
3+
* Find the max profit from buying and selling a stock given their daily prices.
4+
* @examples
5+
* maxProfit([5, 10, 5, 10]); // => 5
6+
* maxProfit([1, 2, 3]); // => 2
7+
* maxProfit([3, 2, 1]); // => 0
8+
* @param {number[]} prices - Array with daily stock prices
9+
*/
10+
function maxProfit(prices) {
11+
// end::description[]
12+
// tag::solution[]
13+
let max = 0;
14+
let local = Infinity;
15+
for (let i = 0; i < prices.length; i++) {
16+
local = Math.min(local, prices[i]);
17+
max = Math.max(max, prices[i] - local);
18+
}
19+
return max;
20+
}
21+
// end::solution[]
22+
23+
// tag::maxProfitBrute1[]
24+
function maxProfitBrute1(prices) {
25+
let max = 0;
26+
for (let i = 0; i < prices.length; i++) {
27+
for (let j = i + 1; j < prices.length; j++) {
28+
max = Math.max(max, prices[j] - prices[i]);
29+
}
30+
}
31+
return max;
32+
}
33+
// end::maxProfitBrute1[]
34+
35+
36+
module.exports = { maxProfitBrute1, maxProfit };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const { maxProfitBrute1, maxProfit } = require('./buy-sell-stock');
2+
3+
describe('Best Time to Buy and Sell Stocks', () => {
4+
[maxProfitBrute1, maxProfit].forEach((fn) => {
5+
describe(`with ${fn.name}`, () => {
6+
it('should work with bullish markets', () => {
7+
expect(fn([1, 2, 3])).toEqual(2);
8+
});
9+
10+
it('should work with bearish markets', () => {
11+
expect(fn([3, 2, 1])).toEqual(0);
12+
});
13+
14+
it('should work with zig-zag markets', () => {
15+
expect(fn([5, 10, 5, 10, 5, 10, 5, 10])).toEqual(5);
16+
});
17+
});
18+
});
19+
});

0 commit comments

Comments
 (0)