diff --git a/benchmarks/two-sum-implementations/01-two-sum.js b/benchmarks/two-sum-implementations/01-two-sum.js new file mode 100644 index 00000000..820df298 --- /dev/null +++ b/benchmarks/two-sum-implementations/01-two-sum.js @@ -0,0 +1,13 @@ +// Brute force: O(n^2) | O(1) +function twoSum(nums, target) { + for (let i = 0; i < nums.length - 1; i++) { // O(n^2) + for (let j = i + 1; j < nums.length; j++) { // O(n) + if (nums[i] + nums[j] === target) { + return [i, j]; + } + } + } + return []; +} + +module.exports = twoSum; diff --git a/benchmarks/two-sum-implementations/02-two-sum.js b/benchmarks/two-sum-implementations/02-two-sum.js new file mode 100644 index 00000000..9703e670 --- /dev/null +++ b/benchmarks/two-sum-implementations/02-two-sum.js @@ -0,0 +1,19 @@ +// With a HashMap: O(n) | O(n) +function twoSum(nums, target) { + const map = nums.reduce((m, v, i) => { // O(n) + const ids = m.get(v) || []; + ids.push(i); + return m.set(v, ids); + }, new Map()); + + for (let i = 0; i < nums.length; i++) { // O(n) + const diff = target - nums[i]; + if (map.has(diff) && i !== map.get(diff)) { + return [i, map.get(diff)]; + } + } + + return []; +} + +module.exports = twoSum; diff --git a/benchmarks/two-sum-implementations/03-two-sum.js b/benchmarks/two-sum-implementations/03-two-sum.js new file mode 100644 index 00000000..8670622f --- /dev/null +++ b/benchmarks/two-sum-implementations/03-two-sum.js @@ -0,0 +1,18 @@ +// With a HashMap: O(n) | O(n), 1-pass +function twoSum(nums, target) { + const map = new Map(); + + for (let i = 0; i < nums.length; i++) { // O(n) + const complement = target - nums[i]; + + if (map.has(complement)) { + return [map.get(complement), i]; + } + + map.set(nums[i], i); + } + + return []; +} + +module.exports = twoSum; diff --git a/benchmarks/two-sum-implementations/runner.js b/benchmarks/two-sum-implementations/runner.js new file mode 100644 index 00000000..2bd280a1 --- /dev/null +++ b/benchmarks/two-sum-implementations/runner.js @@ -0,0 +1,16 @@ +const assert = require('assert'); + +const twoSum = require('./01-two-sum'); + +function test() { + assert.deepEqual(twoSum([1, 2, 3], 4), [0, 2]); + assert.deepEqual(twoSum([1, 2, 3], 14), []); + + assert.deepEqual(twoSum([2, 2, 2], 4), [0, 1]); + assert.deepEqual(twoSum(Array(1e7).fill(2), 4), [0, 1]); // + // assert.deepEqual(twoSum(Array(1e8).fill(2), 4), [0, 1]); // FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory + // assert.deepEqual(twoSum(Array(1e9).fill(2), 4), [0, 1]); // 1e7 - error 137 - OUT OF MEMORY + console.log('All tests passed!'); +} + +test(); diff --git a/book/content/part04/bubble-sort.asc b/book/content/part04/bubble-sort.asc index ed146f7d..583d8415 100644 --- a/book/content/part04/bubble-sort.asc +++ b/book/content/part04/bubble-sort.asc @@ -3,6 +3,7 @@ ifndef::imagesdir[] :codedir: ../../../src endif::[] +[[bubble-sort]] ==== Bubble Sort (((Bubble Sort))) (((Sorting, Bubble Sort))) diff --git a/book/content/part04/quick-sort.asc b/book/content/part04/quick-sort.asc index ad2dfdbb..314caad8 100644 --- a/book/content/part04/quick-sort.asc +++ b/book/content/part04/quick-sort.asc @@ -83,11 +83,11 @@ With the optimization, Quicksort has an _O(n log n)_ running time. Similar to th - <<Online>>: [big]#️❌# No, the pivot element can be choose at random. - Recursive: Yes - Time Complexity: [big]#✅# <<part01-algorithms-analysis#linearithmic>> _O(n log n)_ -- Space Complexity: [big]#✅# <<part01-algorithms-analysis#constant>> _O(1)_ +- Space Complexity: [big]#✅# <<part01-algorithms-analysis#logarithmic>> _O(log n)_, because of recursion. (((Linearithmic))) (((Runtime, Linearithmic))) -(((Space complexity, Constant))) +(((Space complexity, Logarithmic))) // Resources: // https://www.khanacademy.org/computing/computer-science/algorithms/quick-sort/a/linear-time-partitioning diff --git a/book/content/part04/sorting-algorithms.asc b/book/content/part04/sorting-algorithms.asc index 09135bc8..67ea34a4 100644 --- a/book/content/part04/sorting-algorithms.asc +++ b/book/content/part04/sorting-algorithms.asc @@ -9,7 +9,7 @@ Sorting is one of the most common solutions when we want to extract some insight We can sort to get the maximum or minimum value and many algorithmic problems involves sorting data first. .We are going to explore three basic sorting algorithms _O(n^2^)_ which have low overhead: -- <<part04-algorithmic-toolbox#insertion-sort>> +- <<part04-algorithmic-toolbox#bubble-sort>> - <<part04-algorithmic-toolbox#selection-sort>> - <<part04-algorithmic-toolbox#insertion-sort>> @@ -120,7 +120,7 @@ We explored many algorithms some of them simple and other more performant. Also, [cols="20,80"] |=== | Algorithms | Comments -| <<part04-algorithmic-toolbox#insertion-sort>> | Swap pairs bubbling up largest numbers to the right +| <<part04-algorithmic-toolbox#bubble-sort>> | Swap pairs bubbling up largest numbers to the right | <<part04-algorithmic-toolbox#insertion-sort>> | Look for biggest number to the left and swap it with current | <<part04-algorithmic-toolbox#selection-sort>> | Iterate array looking for smallest value to the right | <<part04-algorithmic-toolbox#merge-sort>> | Split numbers in pairs, sort pairs and join them in ascending order @@ -131,12 +131,11 @@ We explored many algorithms some of them simple and other more performant. Also, .Sorting algorithms time/space complexity and properties |=== | Algorithms | Avg | Best | Worst | Space | Stable | In-place | Online | Adaptive -| <<part04-algorithmic-toolbox#insertion-sort>> | O(n^2^) | O(n) | O(n^2^) | O(1) | Yes | Yes | Yes | Yes +| <<part04-algorithmic-toolbox#bubble-sort>> | O(n^2^) | O(n) | O(n^2^) | O(1) | Yes | Yes | Yes | Yes | <<part04-algorithmic-toolbox#insertion-sort>> | O(n^2^) | O(n) | O(n^2^) | O(1) | Yes | Yes | Yes | Yes | <<part04-algorithmic-toolbox#selection-sort>> | O(n^2^) | O(n^2^) | O(n^2^) | O(1) | No | Yes | No | No | <<part04-algorithmic-toolbox#merge-sort>> | O(n log n) | O(n log n) | O(n log n) | O(n) | Yes | No | No | No -| <<part04-algorithmic-toolbox#quicksort>> | O(n log n) | O(n^2^) | O(n log n) | O(log n) | Yes | Yes | No | No +| <<part04-algorithmic-toolbox#quicksort>> | O(n log n) | O(n log n) | O(n^2^) | O(log n) | No | Yes | No | No // | Tim sort | O(n log n) | O(log n) | Yes | No | No | Yes |=== // end::table[] -