diff --git a/.vscode/settings.json b/.vscode/settings.json index 035ef5b2..c4dcc94b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,17 +1,20 @@ { + "peacock.color": "#f9e64f", "workbench.colorCustomizations": { + "activityBar.activeBackground": "#fbed80", + "activityBar.activeBorder": "#06b9a5", "activityBar.background": "#fbed80", "activityBar.foreground": "#15202b", "activityBar.inactiveForeground": "#15202b99", "activityBarBadge.background": "#06b9a5", "activityBarBadge.foreground": "#15202b", - "titleBar.activeBackground": "#f9e64f", - "titleBar.inactiveBackground": "#f9e64f99", - "titleBar.activeForeground": "#15202b", - "titleBar.inactiveForeground": "#15202b99", "statusBar.background": "#f9e64f", + "statusBar.foreground": "#15202b", "statusBarItem.hoverBackground": "#f7df1e", - "statusBar.foreground": "#15202b" + "titleBar.activeBackground": "#f9e64f", + "titleBar.activeForeground": "#15202b", + "titleBar.inactiveBackground": "#f9e64f99", + "titleBar.inactiveForeground": "#15202b99" }, - "peacock.color": "#f9e64f" + "peacock.remoteColor": "#f9e64f" } diff --git a/book/A-time-complexity-cheatsheet.asc b/book/A-time-complexity-cheatsheet.asc index 64400aaa..b4089138 100644 --- a/book/A-time-complexity-cheatsheet.asc +++ b/book/A-time-complexity-cheatsheet.asc @@ -1,6 +1,5 @@ [appendix] -[[a-time-complexity-cheatsheet]] -== Cheatsheet +== Cheatsheet [[a-time-complexity-cheatsheet]] This section summerize what we are going to cover in the rest of this book. diff --git a/book/B-self-balancing-binary-search-trees.asc b/book/B-self-balancing-binary-search-trees.asc index 249f510c..182bdaa4 100644 --- a/book/B-self-balancing-binary-search-trees.asc +++ b/book/B-self-balancing-binary-search-trees.asc @@ -1,6 +1,5 @@ [appendix] -[[b-self-balancing-binary-search-trees]] -== Self-balancing Binary Search Trees +== Self-balancing Binary Search Trees [[b-self-balancing-binary-search-trees]] Binary Search Trees (BST) are an excellent data structure to find elements very fast _O(log n)_. 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. To be more specific we rotated node `1` to the left to balance the tree. Let's examine all the possible rotation we can do to balance a tree. -[[tree-rotations]] -=== Tree Rotations +=== Tree Rotations [[tree-rotations]] (((Tree Rotations))) We can do single rotations left and right and also we can do double rotations. Let's go one by one. diff --git a/book/C-AVL-tree.asc b/book/C-AVL-tree.asc index 07bae068..1a8afe83 100644 --- a/book/C-AVL-tree.asc +++ b/book/C-AVL-tree.asc @@ -1,6 +1,5 @@ [appendix] -[[c-avl-tree]] -== AVL Tree +== AVL Tree [[c-avl-tree]] (((AVL Tree))) (((Tree, AVL))) 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] The first thing we do is to see if one subtree is longer than the other. If so, then we check the children balance to determine if need a single or double rotation and in which direction. -You can review <> in case you want a refresher. +You can review <> in case you want a refresher. diff --git a/book/D-interview-questions-solutions.asc b/book/D-interview-questions-solutions.asc new file mode 100644 index 00000000..7c0c2ad5 --- /dev/null +++ b/book/D-interview-questions-solutions.asc @@ -0,0 +1,96 @@ +[appendix] +[[d-interview-questions-solutions]] +== Interview Questions Solutions +(((Interview Questions Solutions))) + +=== Solutions for Array Questions +(((Interview Questions Solutions, Arrays))) + +:leveloffset: -1 + +[#array-q-max-subarray] +include::content/part02/array.asc[tag=array-q-max-subarray] + +The first step is making sure we understand the problem well. Let's do basic examples: + +---- +A = [-5, 6, 9, -8] +B = [-1, 6, -3, 8] +---- + +What's the subarray with the maximum sum? For A, it will be `[6, 9]` and for B, it will be `[6, -3, 8]`. + +We could generate all possible subarrays, add them up, and then pick the max number. + +[source, javascript] +---- +include::interview-questions/max-subarray.js[tag=maxSubArrayBrute1] +---- + +This code is simple to understand; however, not very efficient. The runtime is `O(n^3)`. + +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. + +[source, javascript] +---- +include::interview-questions/max-subarray.js[tag=maxSubArrayBrute2] +---- + +The runtime is much better: `O(n)`. Can we still do better? + +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. + +[source, javascript] +---- +include::interview-questions/max-subarray.js[tag=description] +include::interview-questions/max-subarray.js[tag=solution] +---- + +The runtime is `O(n)` and a space complexity of `O(1)`. + + + + +[#array-q-buy-sell-stock] +include::content/part02/array.asc[tag=array-q-buy-sell-stock] + +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). + +[source, javascript] +---- +// zig-zag market +maxProfit([5, 10, 5, 10]); // => 5 +// bullish market +maxProfit([1, 2, 3]); // => 2 +// bearish market +maxProfit([3, 2, 1]); // => 0 +---- + +During the bearish markets, the profit will always be 0. Since if you buy, we are only going to lose. + +We can do a brute force solution doing all combinations: + +[source, javascript] +---- +include::interview-questions/buy-sell-stock.js[tag=maxProfitBrute1] +---- + +The runtime for this solution is `O(n^2)`. + +A better solution is to eliminate the 2nd for loop and only do one pass. + +Algorithm: + +- Do one pass through all the prices + - Keep track of the minimum price seen so far. + - calculate `profit = currentPrice - minPriceSoFar` + - Keep track of the maximun profit seen so far. +- Return maxProfit. + +[source, javascript] +---- +include::interview-questions/buy-sell-stock.js[tag=description] +include::interview-questions/buy-sell-stock.js[tag=solution] +---- + +The runtime is `O(n)` and a space complexity of `O(1)`. diff --git a/book/ch02-git-basics-chapter.asc b/book/ch02-git-basics-chapter.asc deleted file mode 100644 index cb91537b..00000000 --- a/book/ch02-git-basics-chapter.asc +++ /dev/null @@ -1,35 +0,0 @@ -[[ch02-git-basics-chapter]] -== Git Basics - -If you can read only one chapter to get going with Git, this is it. -This chapter covers every basic command you need to do the vast majority of the things you'll eventually spend your time doing with Git. -By the end of the chapter, you should be able to configure and initialize a repository, begin and stop tracking files, and stage and commit changes. -We'll also show you how to set up Git to ignore certain files and file patterns, how to undo mistakes quickly and easily, how to browse the history of your project and view changes between commits, and how to push and pull from remote repositories. - -[[links]] -=== Links - -.Links to DSA -- Chapter: <> -- Section: <> - -// In <> we used it to specify our name, email address and editor preference before we even got started using Git. - -[source,console] ----- -$ git commit ----- - -Doing so launches your editor of choice. -(This is set by your shell's `EDITOR` environment variable -- usually vim or emacs, although you can configure it with whatever you want using the `git config --global core.editor` command as you saw in - -// <>).(((editor, changing default)))(((git commands, config))) - - - - - -=== Summary - -At this point, you can do all the basic local Git operations -- creating or cloning a repository, making changes, staging and committing those changes, and viewing the history of all the changes the repository has been through. -Next, we'll cover Git's killer feature: its branching model. diff --git a/book/config b/book/config index f657e9bf..8d7eb9c3 160000 --- a/book/config +++ b/book/config @@ -1 +1 @@ -Subproject commit f657e9bf4325d4987a30cfc47ad2bbc4bda6b23c +Subproject commit 8d7eb9c34523a92b63164abadf38036ca3088389 diff --git a/book/content/part02/array-vs-list-vs-queue-vs-stack.asc b/book/content/part02/array-vs-list-vs-queue-vs-stack.asc index bc289ed8..b464f17d 100644 --- a/book/content/part02/array-vs-list-vs-queue-vs-stack.asc +++ b/book/content/part02/array-vs-list-vs-queue-vs-stack.asc @@ -31,7 +31,7 @@ In this part of the book, we explored the most used linear data structures such |=== .2+.^s| Data Structure 2+^s| Searching By 3+^s| Inserting at the 3+^s| Deleting from .2+.^s| Space ^|_Index/Key_ ^|_Value_ ^|_beginning_ ^|_middle_ ^|_end_ ^|_beginning_ ^|_middle_ ^|_end_ -| <> ^|O(1) ^|O(n) ^|O(n) ^|O(n) ^|O(1) ^|O(n) ^|O(n) ^|O(1) ^|O(n) +| <> ^|O(1) ^|O(n) ^|O(n) ^|O(n) ^|O(1) ^|O(n) ^|O(n) ^|O(1) ^|O(n) | <> ^|O(n) ^|O(n) ^|O(1) ^|O(n) ^|*O(n)* ^|O(1) ^|O(n) ^|*O(n)* ^|O(n) | <> ^|O(n) ^|O(n) ^|O(1) ^|O(n) ^|*O(1)* ^|O(1) ^|O(n) ^|*O(1)* ^|O(n) | <> ^|- ^|- ^|- ^|- ^|O(1) ^|- ^|- ^|O(1) ^|O(n) diff --git a/book/content/part02/array.asc b/book/content/part02/array.asc index 34cadf6a..4b2c2c7e 100644 --- a/book/content/part02/array.asc +++ b/book/content/part02/array.asc @@ -4,7 +4,7 @@ ifndef::imagesdir[] endif::[] [[array]] -=== Array +=== Array [[array-chap]] (((Array))) (((Data Structures, Linear, Array))) 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 .Fixed vs. Dynamic Size Arrays **** -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. +Some programming languages have fixed size arrays like Java and {cpp}. +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. **** Arrays look like this: @@ -275,46 +276,37 @@ To sum up, the time complexity of an array is: |=== //end::table -==== Array Exercises +==== Interview Questions +(((Interview Questions, Arrays))) -1) Implement an efficient algorithm that rotate an array `a` an `k` number of times. +// tag::array-q-max-subarray[] +===== Max Subarray + +Given an array of integers, find the maximum sum of consecutive elements (subarray). +// end::array-q-max-subarray[] [source, javascript] ---- -/** - * Rotate an array left by k number of times. - * - * @example - * rotateLeft([1,2,3], 1); // [2,3,1] - * rotateLeft([1,2,3,4,5], 4); // [5,1,2,3,4] - * - * rotateLeft(Array(1e6).fill(1), 1e4); // - * - * @param a - The array - * @param k - The number of times the array is rotated - */ -function rotateLeft(a, k) { - // write you code and test with examples +include::../../interview-questions/max-subarray.js[tag=description] + // write you code here } ---- +_Solution: <>_ + +// tag::array-q-buy-sell-stock[] +===== Best Time to Buy and Sell an Stock -2) Implement an algorithm that takes two arrays of numbers and return a new array with the sum. +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) +// end::array-q-buy-sell-stock[] [source, javascript] ---- -/** - * Return the sum of two arrays as a new array. - * - * @example - * sum([1,2,3], [1,1,1]); // [2,3,4] - * sum([1], [9,9,9]); // [1,0,0,0] - * - * @param {number[]} a - Array of numbers. - * @param {number[]} b - Array of numbers. - * @returns {number[]} the sum array. - */ -function sum(a, b) { - // write you code and test with examples +include::../../interview-questions/buy-sell-stock.js[tag=description] + // write you code here } ---- + +_Solution: <>_ + +// https://leetcode.com/problemset/algorithms/?topicSlugs=array diff --git a/book/content/part03/map.asc b/book/content/part03/map.asc index 11106d4f..d5448619 100644 --- a/book/content/part03/map.asc +++ b/book/content/part03/map.asc @@ -24,7 +24,7 @@ In short, you set `key`/`value` pair and then you can get the `value` using the 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: * *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)*. -* *TreeMap*: it’s a map implementation that uses a self-balanced Binary Search Tree (like <>). The BST nodes store the key, and the value and nodes are sorted by key guaranteeing an *O(log n)* look up. +* *TreeMap*: it’s a map implementation that uses a self-balanced Binary Search Tree (like <>). The BST nodes store the key, and the value and nodes are sorted by key guaranteeing an *O(log n)* look up. <<< include::hashmap.asc[] diff --git a/book/content/part03/time-complexity-graph-data-structures.asc b/book/content/part03/time-complexity-graph-data-structures.asc index a62d68c4..ed85c1a6 100644 --- a/book/content/part03/time-complexity-graph-data-structures.asc +++ b/book/content/part03/time-complexity-graph-data-structures.asc @@ -14,7 +14,7 @@ In this section, we learned about Graphs applications, properties and how we can .2+.^s| Data Structure 2+^s| Searching By .2+^.^s| Insert .2+^.^s| Delete .2+^.^s| Space Complexity ^|_Index/Key_ ^|_Value_ | <> ^|- ^|O(n) ^|O(n) ^|O(n) ^|O(n) -| <> ^|- ^|O(log n) ^|O(log n) ^|O(log n) ^|O(n) +| <> ^|- ^|O(log n) ^|O(log n) ^|O(log n) ^|O(n) | Hash Map (naïve) ^|O(n) ^|O(n) ^|O(n) ^|O(n) ^|O(n) | <> (optimized) ^|O(1) ^|O(n) ^|O(1)* ^|O(1) ^|O(n) | <> (Red-Black Tree) ^|O(log n) ^|O(n) ^|O(log n) ^|O(log n) ^|O(n) diff --git a/book/content/preface.asc b/book/content/preface.asc index bb780633..afcc20c6 100644 --- a/book/content/preface.asc +++ b/book/content/preface.asc @@ -3,7 +3,7 @@ === What is in this book? -_{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 <> and <>) +_{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 <> and <>) 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. @@ -82,4 +82,4 @@ Measurement is the first step that leads to control and eventually to improvemen 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. -To send us feedback, e-mail us at hello+dsajs@adrianmejia.com, send a tweet to https://twitter.com/iAmAdrianMejia[@iAmAdrianMejia], or using the hash tags `#dsaJS`, `#javascript` and `#algorithms`. +To send us feedback, e-mail us at hello+dsajs@adrianmejia.com, send a tweet to https://twitter.com/iAmAdrianMejia[@iAmAdrianMejia], or using the hash tag `#dsaJS`. diff --git a/book/index.asc b/book/index.asc index 4312be40..d07d9fba 100644 --- a/book/index.asc +++ b/book/index.asc @@ -1,5 +1,4 @@ [index] -[[index]] -== Index +== Index [[index]] ifndef::backend-pdf[Topical index only available on the PDF version.] diff --git a/book/interview-questions/buy-sell-stock.js b/book/interview-questions/buy-sell-stock.js new file mode 100644 index 00000000..47422ff0 --- /dev/null +++ b/book/interview-questions/buy-sell-stock.js @@ -0,0 +1,36 @@ +// tag::description[] +/** + * Find the max profit from buying and selling a stock given their daily prices. + * @examples + * maxProfit([5, 10, 5, 10]); // => 5 + * maxProfit([1, 2, 3]); // => 2 + * maxProfit([3, 2, 1]); // => 0 + * @param {number[]} prices - Array with daily stock prices + */ +function maxProfit(prices) { +// end::description[] +// tag::solution[] + let max = 0; + let local = Infinity; + for (let i = 0; i < prices.length; i++) { + local = Math.min(local, prices[i]); + max = Math.max(max, prices[i] - local); + } + return max; +} +// end::solution[] + +// tag::maxProfitBrute1[] +function maxProfitBrute1(prices) { + let max = 0; + for (let i = 0; i < prices.length; i++) { + for (let j = i + 1; j < prices.length; j++) { + max = Math.max(max, prices[j] - prices[i]); + } + } + return max; +} +// end::maxProfitBrute1[] + + +module.exports = { maxProfitBrute1, maxProfit }; diff --git a/book/interview-questions/buy-sell-stock.spec.js b/book/interview-questions/buy-sell-stock.spec.js new file mode 100644 index 00000000..bce80375 --- /dev/null +++ b/book/interview-questions/buy-sell-stock.spec.js @@ -0,0 +1,19 @@ +const { maxProfitBrute1, maxProfit } = require('./buy-sell-stock'); + +describe('Best Time to Buy and Sell Stocks', () => { + [maxProfitBrute1, maxProfit].forEach((fn) => { + describe(`with ${fn.name}`, () => { + it('should work with bullish markets', () => { + expect(fn([1, 2, 3])).toEqual(2); + }); + + it('should work with bearish markets', () => { + expect(fn([3, 2, 1])).toEqual(0); + }); + + it('should work with zig-zag markets', () => { + expect(fn([5, 10, 5, 10, 5, 10, 5, 10])).toEqual(5); + }); + }); + }); +}); diff --git a/book/interview-questions/max-subarray.data.js b/book/interview-questions/max-subarray.data.js new file mode 100644 index 00000000..3fce5f6a --- /dev/null +++ b/book/interview-questions/max-subarray.data.js @@ -0,0 +1 @@ +module.exports = [-57,9,-72,-72,-62,45,-97,24,-39,35,-82,-4,-63,1,-93,42,44,1,-75,-25,-87,-16,9,-59,20,5,-95,-41,4,-30,47,46,78,52,74,93,-3,53,17,34,-34,34,-69,-21,-87,-86,-79,56,-9,-55,-69,3,5,16,21,-75,-79,2,-39,25,72,84,-52,27,36,98,20,-90,52,-85,44,94,25,51,-27,37,41,-6,-30,-68,15,-23,11,-79,93,-68,-78,90,11,-41,-8,-17,-56,17,86,56,15,7,66,-56,-2,-13,-62,-77,-62,-12,37,55,81,-93,86,-27,-39,-3,-30,-46,6,-8,-79,-83,50,-10,-24,70,-93,-38,27,-2,45,-7,42,-57,79,56,-57,93,-56,79,48,-98,62,11,-48,-77,84,21,-47,-10,-87,-49,-17,40,40,35,10,23,97,-63,-79,19,6,39,62,-38,-27,81,-68,-7,60,79,-28,-1,-33,23,22,-48,-79,51,18,-66,-98,-98,50,41,13,-63,-59,10,-49,-38,-70,56,77,68,95,-73,26,-73,20,-14,83,91,61,-50,-9,-40,1,11,-88,-80,21,89,97,-29,8,10,-15,48,97,35,86,-96,-9,64,48,-37,90,-26,-10,-13,36,-27,-45,-3,-1,45,34,77,-66,22,73,54,11,70,-97,-81,-43,-13,44,-69,-78,30,-66,-11,-29,58,52,-61,-68,-81,25,44,-32,57,-81,66,2,52,43,35,-26,16,-33,61,-37,-54,80,-3,32,24,27,30,-69,38,-81,2,-4,47,17,5,42,-58,-51,-90,98,-33,76,-22,95,-4,89,-31,-87,-44,-69,-48,1,87,48,-90,-12,-24,39,18,-86,35,96,-14,-41,13,90,-98,32,-83,-89,7,-17,63,84,-21,-40,51,24,-51,83,31,0,-38,-5,-74,-29,59,1,87,-22,-9,-1,-49,76,57,41,44,35,-27,60,23,56,-80,-14,41,-2,22,-31,99,47,-48,7,-75,13,-97,-50,61,61,27,48,-84,94,-76,-56,70,57,84,-9,-7,-66,-49,-84,89,-29,-22,7,45,-99,75,21,24,-95,-71,48,17,-92,74,-22,45,1,-97,61,-5,-74,81,-57,83,42,33,-47,75,61,-55,41,-68,22,-51,53,-1,-99,-25,-76,-95,3,48,-1,-13,23,53,-68,-76,33,92,-4,35,50,38,18,-8,-52,47,-33,-91,91,85,-60,14,-89,93,89,-89,-55,89,92,47,38,-9,-66,-39,-79,-58,-39,53,-65,56,-11,61,-29,83,-46,19,31,-3,27,-1,-18,67,-87,-8,37,79,-20,58,68,-28,-18,-17,39,-8,43,59,33,81,13,44,37,-98,6,85,84,59,4,-8,-44,-69,91,15,74,80,83,-12,59,-37,-54,5,34,27,87,-50,-81,8,-90,52,-11,-1,-4,-97,0,78,87,-39,37,-32,30,70,-1,21,-38,-50,-22,-55,15,-85,8,60,19,-81,-35,-17,-31,-40,90,-45,-88,-44,53,-15,-41,-70,-37,-77,-33,77,-9,96,24,66,-6,85,92,72,-70,7,86,14,-32,-18,33,9,64,78,68,32,-90,57,87,62,-58,-77,68,-19,-54,-65,-42,13,-68,58,-44,25,43,-52,-26,73,55,-63,-13,-77,18,96,31,-40,51,-1,91,60,-44,55,22,-26,78,-10,32,-99,2,66,13,33,25,68,-65,-32,-84,-14,-82,70,22,5,69,-59,-22,-23,0,-70,53,-32,89,85,-77,-11,-40,77,55,68,77,-43,34,-33,66,-41,-88,-98,27,-72,-13,21,74,85,-74,21,-74,-19,97,2,10,50,46,-1,13,69,87,72,23,20,40,1,76,-49,67,43,10,79,21,-86,83,84,34,34,69,37,-45,72,-82,-70,-26,27,56,97,-97,-31,66,67,-82,-11,-13,57,66,-37,85,11,82,-5,-33,3,-15,-50,-13,95,60,-66,9,-84,-94,26,-78,-44,-70,77,-47,-90,-53,95,76,-36,-38,-60,98,-72,-21,83,15,-38,-45,81,41,16,-69,-94,11,91,-84,-79,83,-79,23,-95,-24,30,58,6,39,-95,1,-8,-54,62,31,-56,67,86,-96,-18,-75,-42,-36,66,73,-29,48,-39,-61,63,-42,98,60,81,-97,-64,11,61,18,-73,42,-80,18,87,58,-51,-69,2,-88,-66,84,-63,-32,-75,79,-82,-28,27,-21,11,-33,13,9,-73,-6,-11,-61,81,-73,57,-92,45,53,25,33,11,50,40,90,62,51,74,75,-81,75,54,-86,-53,-42,-8,34,1,-95,-79,27,-24,-14,42,-66,12,-24,-58,-66,-71,43,66,17,-29,-16,7,-90,-65,-42,84,-70,-90,15,-57,-67,49,11,67,-50,-7,64,53,68,-50,-5,78,38,71,96,71,76,40,15,-7,87,98,76,96,-90,-66,57,-61,-57,-51,-41,-47,97,69,-80,-53,-61,83,76,83,-90,-29,62,47,-81,58,18,95,-2,-67,-12,-38,-92,-35,-65,-83,-25,91,-44,-5,-83,-9,47,-86,-40,43,-63,-1,3,-87,-18,12,-39,-79,-41,-21,79,53,-26,-46,63,39,16,70,80,50,87,-45,19,-80,26,35,10,-27,26,46,92,62,-55,-5,52,4,-93,-87,1,-58,-9,-20,95,42,34,58,-19,-73,5,-39,53,-31,-8,-28,-12,95,84,97,-55,10,44,-62,-51,65,32,-99,-54,16,89,47,57,-42,-96,52,99,14,-13,-43,40,69,-6,-6,-62,85,42,26,80,26,0,-74,-87,-79,-60,-38,63,71,-61,85,-13,-71,9,-78,-14,13,50,-38,-73,-85,18,44,83,-88,-85,-79,73,56,23,31,-40,-99,33,-51,97,72,-13,60,20,26,46,84,31,-45,-94,93,67,55,-45,71,69,49,15,52,37,29,50,-13,-38,-50,-82,-2,-73,27,47,-75,-24,-66,84,96,36,7,80,-56,62,62,-63,6,17,-32,-46,-13,93,45,-84,30,-26,42,-82,13,92,-88,-89,-81,16,34,-57,91,45,-95,87,-42,11,44,2,-50,6,15,33,-76,83,86,-13,76,32,-21,-16,82,-78,-22,-28,90,-34,-40,-91,81,93,-71,73,15,-90,37,73,-3,-41,-48,47,64,66,-43,64,49,-57,-72,3,51,7,63,11,28,-82,82,18,-17,-58,3,-58,-87,8,-85,27,17,28,-23,-85,86,28,38,28,-5,94,-31,-79,-86,-3,0,65,80,-60,-24,8,-43,-65,-97,40,-23,-18,81,-11,90,72,92,-16,0,-30,-25,-36,97,-87,68,-31,83,-63,-33,97,10,66,39,-10,-93,91,74,-37,-74,53,79,-21,-64,37,67,-74,9,60,9,86,-70,84,-73,-96,73,94,-50,57,-69,16,31,18,-18,-53,-92,-35,-62,59,5,-60,12,-16,19,47,-78,-14,49,7,-77,-64,-7,-71,96,19,-67,69,-10,-18,3,-2,97,-89,-84,-44,-43,99,-2,-6,58,-97,11,-29,-14,-70,94,-16,-8,44,91,15,79,-39,20,75,57,52,21,-53,-89,-98,44,84,-88,36,-82,-31,36,15,39,-29,17,-50,41,79,-21,13,-36,71,-66,-68,-37,89,-8,82,41,-74,12,-38,-50,-1,-37,70,-39,-48,7,-22,20,-57,69,-41,13,-14,-14,-68,-58,64,21,5,12,54,13,51,43,-94,11,-16,-92,99,22,-43,-2,62,-72,58,-86,11,-87,33,53,81,68,-57,-56,-46,-49,-14,95,71,67,-16,2,-19,-87,-78,-37,0,-18,-30,-1,-95,4,96,66,31,32,79,-81,44,-11,48,3,-66,90,46,-12,-81,-91,-40,66,76,20,-54,-43,9,-33,19,-91,49,88,7,30,-8,-19,-4,99,-87,-48,-82,33,40,65,-64,73,33,59,-62,28,67,-26,-29,43,71,16,99,-20,83,18,-11,9,-16,72,-61,52,-47,34,29,-58,85,23,75,2,-34,87,-48,75,46,-33,3,-9,40,73,-66,-12,-10,-89,68,-50,5,-66,58,88,82,96,18,-64,7,-53,-23,-31,69,-71,47,-88,-83,98,86,39,-35,-34,-70,82,-60,-36,-30,6,-26,-85,55,55,-75,-10,44,84,-37,-38,-80,69,-15,-27,-85,-69,-21,61,-57,-5,59,-71,-66,-98,-5,-59,60,11,4,-93,93,54,98,48,9,99,-85,-70,83,-23,-32,79,-77,52,-47,-63,60,8,97,-97,-97,33,-92,-87,11,-21,-47,-29,66,33,-45,59,-36,-47,-16,50,-48,-2,79,-64,51,-75,-85,73,76,-56,-90,13,51,83,-8,30,17,-23,20,-72,55,49,-24,-1,-17,7,-42,23,59,42,-27,87,-83,-47,99,68,-46,91,18,-93,-88,28,20,40,-12,-88,-30,-95,-12,66,-90,-79,16,-38,19,75,68,76,-2,27,-5,71,-9,12,-99,-32,-43,-46,-41,74,-40,-53,-21,79,86,67,68,-66,48,-67,99,57,-47,15,-81,71,-33,86,25,65,-10,96,36,58,-15,13,-74,41,66,-39,-7,-97,7,71,59,-6,15,27,4,-36,59,3,-79,89,95,-83,37,-38,79,-38,-96,-53,-41,39,-95,43,-71,-93,-38,71,-33,54,74,50,2,10,-79,-82,-86,24,-19,49,-95,1,38,99,-6,-24,-62,-26,14,-58,20,49,57,1,-7,63,-16,31,34,50,-15,-15,-23,86,94,-2,-96,-92,98,-39,34,-97,62,-28,78,-67,24,93,6,-61,-65,-97,87,68,-20,-43,31,63,87,-57,-10,-51,27,67,-87,-1,-35,-84,-17,-60,-23,-83,-57,-84,-34,-79,-52,89,-86,31,-95,-75,10,69,70,90,-97,1,53,67,43,-56,-84,-52,87,-72,46,-71,-79,-71,-32,-26,-77,10,-34,-12,8,-10,-46,-2,-79,-41,0,8,-95,-30,-2,83,47,-72,50,-9,-29,43,15,-65,70,-39,-37,67,-34,31,-59,-12,-82,6,75,25,96,-70,-99,93,-35,0,1,-54,69,75,-71,16,-96,56,83,-49,-1,-2,-14,-31,35,48,-86,-98,-21,-46,-34,-3,37,-58,98,10,-52,98,3,-11,-2,81,11,-33,56,16,60,36,-28,43,87,47,-81,-50,93,53,97,-93,31,-46,-40,97,27,73,-84,25,-17,-60,1,63,5,98,44,-84,-57,-23,8,79,90,57,22,54,4,17,-96,-3,-29,-99,3,78,-69,40,52,57,13,67,-40,73,83,60,36,-12,35,-43,-20,54,10,88,33,0,45,-67,-46,-51,49,-43,23,96,-65,-74,52,-35,42,4,99,-67,-28,-41,-94,-45,-81,18,43,53,74,99,-15,-39,87,-82,61,9,-73,91,58,76,-74,-19,49,-63,-17,1,1,-97,-94,-23,-65,-46,35,-83,8,53,34,-72,-16,-15,-95,68,45,91,62,-17,1,89,-48,-64,42,-46,-7,-9,-10,52,69,67,54,74,-55,65,-72,79,58,12,10,-31,17,70,53,21,38,-24,-11,-23,35,89,-34,86,-98,-92,-60,-6,-24,6,-53,-55,-26,77,-81,18,20,-77,-26,-22,11,60,47,-72,30,-23,25,-55,52,-85,22,-12,80,87,-49,59,72,-32,-47,-52,73,-24,-8,-76,-69,-13,18,50,9,92,-95,96,52,51,-98,-40,-71,26,4,57,17,-74,-78,-25,90,-50,-66,39,17,-37,86,-33,39,-45,-9,69,41,-91,-4,-73,77,0,-77,7,-48,-76,66,-43,50,-30,90,-56,-27,-87,-5,-37,-38,28,-98,55,91,64,-78,7,-81,12,-47,36,-2,48,62,-25,-75,84,81,-47,-91,24,-14,35,94,-23,78,-56,-34,-49,-17,27,78,-16,-18,46,-75,-20,-70,-80,92,-18,55,-10,-93,17,41,-68,1,0,-39,-14,-76,47,-79,94,-76,76,-62,-11,-73,20,92,81,80,-49,28,-95,30,34,-99,22,-83,55,88,99,-28,7,-69,50,-93]; diff --git a/book/interview-questions/max-subarray.js b/book/interview-questions/max-subarray.js new file mode 100644 index 00000000..3684740a --- /dev/null +++ b/book/interview-questions/max-subarray.js @@ -0,0 +1,54 @@ +// tag::description[] +/** + * Find the maximun sum of contiguous elements in an array. + * @examples + * maxSubArray([1, -3, 10, -5]); // => 10 + * maxSubArray([-3,4,-1,2,1,-5]); // => 6 + * @param {number[]} a - Array + */ +function maxSubArray(a) { +// end::description[] +// tag::solution[] + let max = -Infinity; + let local = 0; + + a.forEach((n) => { + local = Math.max(n, local + n); + max = Math.max(max, local); + }); + + return max; +} +// end::solution[] + +// tag::maxSubArrayBrute1[] +function maxSubArrayBrute1(nums) { + let max = -Infinity; + + for (let i = 0; i < nums.length; i++) { // O(n^3) + for (let j = i + 1; j <= nums.length; j++) { // O(n^2) + const sum = nums.slice(i, j).reduce((a, n) => n + a, 0); // O(n) + max = Math.max(max, sum); // O(1) + } + } + + return max; +} +// end::maxSubArrayBrute1[] + +// tag::maxSubArrayBrute2[] +function maxSubArrayBrute2(nums) { + let max = -Infinity; + + for (let i = 0; i < nums.length; i++) { // O(n) * O(n) + let local = 0; + for (let j = i; j < nums.length; j++) { // O(n) + local += nums[j]; + max = Math.max(max, local); + } + } + return max; +} +// end::maxSubArrayBrute2[] + +module.exports = { maxSubArrayBrute1, maxSubArrayBrute2, maxSubArray }; diff --git a/book/interview-questions/max-subarray.spec.js b/book/interview-questions/max-subarray.spec.js new file mode 100644 index 00000000..e8a43048 --- /dev/null +++ b/book/interview-questions/max-subarray.spec.js @@ -0,0 +1,16 @@ +const { maxSubArray, maxSubArrayBrute1, maxSubArrayBrute2 } = require('./max-subarray'); +const largeArray = require('./max-subarray.data'); + +describe('Max Subarray Sum', () => { + [maxSubArray, maxSubArrayBrute1, maxSubArrayBrute2].forEach((fn) => { + describe(`with ${fn.name}`, () => { + it('should work with small arrays', () => { + expect(fn([-2, 1, -3, 4, -1, 2, 1, -5, 4])).toEqual(6); + }); + + it('should work with large arrays', () => { + expect(fn(largeArray)).toEqual(4853); + }); + }); + }); +}); diff --git a/book/part02-linear-data-structures.asc b/book/part02-linear-data-structures.asc index ca76e78a..c357fb1d 100644 --- a/book/part02-linear-data-structures.asc +++ b/book/part02-linear-data-structures.asc @@ -6,7 +6,7 @@ Data Structures comes in many flavors. There’s no one to rule them all. You ha Even though in your day-to-day, you might not need to re-implementing them, knowing how they work internally would help you know when to use one over the other or even tweak them to create a new one. We are going to explore the most common data structures' time and space complexity. .In this part we are going to learn about the following linear data structures: -- <> +- <> - <> - <> - <> diff --git a/book/readme.asc b/book/readme.asc index 2e291afe..48f92fbe 100644 --- a/book/readme.asc +++ b/book/readme.asc @@ -60,6 +60,8 @@ include::B-self-balancing-binary-search-trees.asc[] include::C-AVL-tree.asc[] +include::D-interview-questions-solutions.asc[] + include::index.asc[] // ifndef::ebook-format[include::index.asc[]] diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000..59b40aec --- /dev/null +++ b/jest.config.js @@ -0,0 +1,4 @@ +module.exports = { + name: 'dsa.js', + testPathIgnorePatterns: ['/node_modules/', '/dist/', '/lab/', '/benchmarks/', '/coverage/'], +}; diff --git a/lab/exercises/01-arrays/rotate-array-left.js b/lab/exercises/01-arrays/rotate-array-left.js index 88640b89..236cfc73 100644 --- a/lab/exercises/01-arrays/rotate-array-left.js +++ b/lab/exercises/01-arrays/rotate-array-left.js @@ -1,3 +1,4 @@ +// tag::description[] /** * Rotate an array left by k number of times. * @@ -11,5 +12,23 @@ * @param k - The number of times the array is rotated */ function rotateLeft(a, k) { - // write you code and test with examples +// end::description[] +// tag::solution[] + const moves = k % a.length; + for (let i = 0; i < moves; i++) { + a.push(a.shift()); + } + return a; } +// end::solution[] + +// tag::bruteForce[] +function rotateLeftBruteForce(a, k) { + for (let i = 0; i < k; i++) { + a.push(a.shift()); + } + return a; +} +// end::bruteForce[] + +module.exports = { rotateLeft, rotateLeftBruteForce }; diff --git a/lab/exercises/01-arrays/rotate-array-left.spec.js b/lab/exercises/01-arrays/rotate-array-left.spec.js new file mode 100644 index 00000000..990e1454 --- /dev/null +++ b/lab/exercises/01-arrays/rotate-array-left.spec.js @@ -0,0 +1,23 @@ +const { rotateLeft, rotateLeftBruteForce } = require('./rotate-array-left'); + +const largeArray = Array(1e6).fill(1).map((t) => t * Math.random()); + +[rotateLeft, rotateLeftBruteForce].forEach((fn) => { + xdescribe(`Rotate Left ${fn.name}`, () => { + describe('when data is small', () => { + it('should work with 1', () => { + expect(fn([1, 2, 3], 1)).toEqual([2, 3, 1]); + }); + + it('should work with 4', () => { + expect(fn([1, 2, 3, 4, 5], 4)).toEqual([5, 1, 2, 3, 4]); + }); + }); + + xdescribe('when data is large', () => { + it('should work at scale', () => { + expect(fn(largeArray, 75863)).toEqual(largeArray); + }); + }); + }); +}); diff --git a/notes.md b/notes.md index 21f8845e..c868f237 100644 --- a/notes.md +++ b/notes.md @@ -117,3 +117,7 @@ alert('foo'); console.log('bar'); /* eslint-enable no-alert */ ``` + +# Asciidoctor Manual + +https://asciidoctor.org/docs/user-manual/ diff --git a/package.json b/package.json index 24c3fdd2..26f202ee 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,10 @@ "src/**/*.js" ], "scripts": { - "test": "jest src/", - "watch": "jest src/ --watch --coverage", - "coverage": "jest src/ --coverage && open coverage/lcov-report/index.html", + "test": "jest --verbose", + "watch": "jest --watch --verbose --coverage", + "coverage": "jest --coverage && open coverage/lcov-report/index.html", + "coverage:win": "jest --coverage && cmd.exe /C start coverage/lcov-report/index.html", "lint": "npx eslint --fix --format codeframe src/", "ci": "npx eslint src/ && jest src/ --coverage", "semantic-release": "semantic-release",