From 6855dce230067b98b1608e7718ff13bc28923fe9 Mon Sep 17 00:00:00 2001 From: ashudeshwal999 Date: Sat, 5 Oct 2019 19:24:10 +0530 Subject: [PATCH 01/25] --update : add doubly link list --- .../DoublyLinkedList/index.js | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/_DataStructures_/DoublyLinkedList/index.js diff --git a/src/_DataStructures_/DoublyLinkedList/index.js b/src/_DataStructures_/DoublyLinkedList/index.js new file mode 100644 index 00000000..36fc3106 --- /dev/null +++ b/src/_DataStructures_/DoublyLinkedList/index.js @@ -0,0 +1,68 @@ +/* eslint-disable class-methods-use-this */ +class Node { + constructor(data, previous, next) { + this.data = data; + this.previous = previous; + this.next = next; + } +} + +class DoublyLinkedList { + constructor() { + // head -> tail + // head <- tail + this.head = new Node(null, null, null); + this.tail = new Node(null, null, null); + this.head.next = this.tail; // head next point to tail + this.tail.previous = this.head; // tail previous point to head + } + + addAtBeginning(value) { + const newNode = new Node(value, this.head, this.head.next); + this.head.next.previous = newNode; + this.head.next = newNode; + } + + addAtEnd(value) { + const newNode = new Node(value, this.tail.previous, this.tail); + this.tail.previous.next = newNode; + this.tail.previous = newNode; + } + + removeAtBeginning() { + this.remove(this.head.next); + } + + removeAtEnd() { + this.remove(this.tail.previous); + } + + remove(node) { + const previousNode = node.previous; + const nextNode = node.next; + previousNode.next = nextNode; + nextNode.previous = previousNode; + } + + length() { + let address = this.head.next; + let count = 0; + while (address !== this.tail) { + count += 1; + address = address.next; + } + return count; + } + + display() { + let address = this.head.next; + while (address !== this.tail) { + console.log(address.data); + address = address.next; + } + } +} + +module.exports = { + DoublyLinkedList, +}; From 84feda9fa9f8b37eed41b7514c6889b2c577ed89 Mon Sep 17 00:00:00 2001 From: ashudeshwal999 Date: Sat, 5 Oct 2019 21:15:10 +0530 Subject: [PATCH 02/25] --refactor : refactor length function --- src/_DataStructures_/DoublyLinkedList/index.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/_DataStructures_/DoublyLinkedList/index.js b/src/_DataStructures_/DoublyLinkedList/index.js index 36fc3106..65f7a4ab 100644 --- a/src/_DataStructures_/DoublyLinkedList/index.js +++ b/src/_DataStructures_/DoublyLinkedList/index.js @@ -4,6 +4,7 @@ class Node { this.data = data; this.previous = previous; this.next = next; + this.length = 0; } } @@ -21,20 +22,24 @@ class DoublyLinkedList { const newNode = new Node(value, this.head, this.head.next); this.head.next.previous = newNode; this.head.next = newNode; + this.length += 1; } addAtEnd(value) { const newNode = new Node(value, this.tail.previous, this.tail); this.tail.previous.next = newNode; this.tail.previous = newNode; + this.length += 1; } removeAtBeginning() { this.remove(this.head.next); + this.length -= 1; } removeAtEnd() { this.remove(this.tail.previous); + this.length -= 1; } remove(node) { @@ -45,13 +50,7 @@ class DoublyLinkedList { } length() { - let address = this.head.next; - let count = 0; - while (address !== this.tail) { - count += 1; - address = address.next; - } - return count; + return this.length; } display() { From 53ac17abdf458390a88ee5fef34e805000e94946 Mon Sep 17 00:00:00 2001 From: ashudeshwal999 Date: Sat, 5 Oct 2019 22:29:30 +0530 Subject: [PATCH 03/25] --fix : fix doublyLinkedList length --- src/_DataStructures_/DoublyLinkedList/index.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/_DataStructures_/DoublyLinkedList/index.js b/src/_DataStructures_/DoublyLinkedList/index.js index 65f7a4ab..522924b9 100644 --- a/src/_DataStructures_/DoublyLinkedList/index.js +++ b/src/_DataStructures_/DoublyLinkedList/index.js @@ -4,7 +4,6 @@ class Node { this.data = data; this.previous = previous; this.next = next; - this.length = 0; } } @@ -16,30 +15,31 @@ class DoublyLinkedList { this.tail = new Node(null, null, null); this.head.next = this.tail; // head next point to tail this.tail.previous = this.head; // tail previous point to head + this.size = 0; } addAtBeginning(value) { const newNode = new Node(value, this.head, this.head.next); this.head.next.previous = newNode; this.head.next = newNode; - this.length += 1; + this.size += 1; } addAtEnd(value) { const newNode = new Node(value, this.tail.previous, this.tail); this.tail.previous.next = newNode; this.tail.previous = newNode; - this.length += 1; + this.size += 1; } removeAtBeginning() { this.remove(this.head.next); - this.length -= 1; + this.size -= 1; } removeAtEnd() { this.remove(this.tail.previous); - this.length -= 1; + this.size -= 1; } remove(node) { @@ -50,7 +50,7 @@ class DoublyLinkedList { } length() { - return this.length; + return this.size; } display() { @@ -62,6 +62,4 @@ class DoublyLinkedList { } } -module.exports = { - DoublyLinkedList, -}; +module.exports = DoublyLinkedList; From 7b9dd7ead0efae8c39aa04447b7710eb2a1dbe0c Mon Sep 17 00:00:00 2001 From: ashudeshwal999 Date: Sat, 5 Oct 2019 22:33:08 +0530 Subject: [PATCH 04/25] --update : add LRUCache data structure --- .../DoublyLinkedList/lru-cache/index.js | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/_DataStructures_/DoublyLinkedList/lru-cache/index.js diff --git a/src/_DataStructures_/DoublyLinkedList/lru-cache/index.js b/src/_DataStructures_/DoublyLinkedList/lru-cache/index.js new file mode 100644 index 00000000..d843ea59 --- /dev/null +++ b/src/_DataStructures_/DoublyLinkedList/lru-cache/index.js @@ -0,0 +1,71 @@ +/* +Least recently used (LRU) - cache implementation + +get(key) – Get the value (will always be positive) of the key if the key exists in the cache, otherwise return false. +Complexity: O(1) + +set(key, value) – Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item. +Complexity: O(1) +*/ + +const DoublyLinkedList = require('../index'); + +class LRUCache { + constructor(n) { + this.size = n; + this.map = new Map(); + this.list = new DoublyLinkedList(); + } + + // this method will work in O(1) + set(key, value) { + const data = { + key, + value, + }; + if (!this.map.has(key)) { + this.list.addAtBeginning(data); + this.map.set(key, this.list.head.next); + + if (this.list.length() > this.size) { + const lastNode = this.list.tail.previous.data; + this.map.delete(lastNode.key); + this.list.removeAtEnd(); + } + } else { + this.list.remove(this.map.get(key)); + this.list.addAtBeginning(data); + this.map.set(key, this.list.head.next); + } + } + + // this method will work in O(1) + get(key) { + if (this.map.has(key)) { + const node = this.map.get(key); + const { value } = node.data; + this.list.remove(node); + this.list.addAtBeginning({ + key, + value, + }); + this.map.set(key, this.list.head.next); + } + return false; + } +} + +// const lru = new LRUCache(3); +// lru.set(1, 1); +// lru.set(2, 2); +// lru.set(3, 3); +// lru.set(4, 4); +// lru.set(5, 5); +// lru.set(2, 2); +// lru.get(5, 5); +// lru.list.display(); + + +module.exports = { + LRUCache, +}; From 261695e960902157159b9c57c243dd98977b7c49 Mon Sep 17 00:00:00 2001 From: ashudeshwal999 Date: Sat, 5 Oct 2019 23:54:26 +0530 Subject: [PATCH 05/25] --update : move LRU cache into _Algorithms_ --- .../DoublyLinkedList => _Algorithms_}/lru-cache/index.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{_DataStructures_/DoublyLinkedList => _Algorithms_}/lru-cache/index.js (100%) diff --git a/src/_DataStructures_/DoublyLinkedList/lru-cache/index.js b/src/_Algorithms_/lru-cache/index.js similarity index 100% rename from src/_DataStructures_/DoublyLinkedList/lru-cache/index.js rename to src/_Algorithms_/lru-cache/index.js From aae91425bc7a6c239bbbeb762cd5e419d72b72f9 Mon Sep 17 00:00:00 2001 From: ashudeshwal999 Date: Sat, 5 Oct 2019 23:55:52 +0530 Subject: [PATCH 06/25] --fix : fix require --- src/_Algorithms_/lru-cache/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_Algorithms_/lru-cache/index.js b/src/_Algorithms_/lru-cache/index.js index d843ea59..beb96347 100644 --- a/src/_Algorithms_/lru-cache/index.js +++ b/src/_Algorithms_/lru-cache/index.js @@ -8,7 +8,7 @@ set(key, value) – Set or insert the value if the key is not already present. W Complexity: O(1) */ -const DoublyLinkedList = require('../index'); +const DoublyLinkedList = require('../../_DataStructures_/DoublyLinkedList/index'); class LRUCache { constructor(n) { From 2db844143da8ef9b3b0f420488c437b12c30d74a Mon Sep 17 00:00:00 2001 From: ashudeshwal999 Date: Sun, 6 Oct 2019 01:05:38 +0530 Subject: [PATCH 07/25] --update : README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index c839b342..c86c931a 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct - [Queue](src/_DataStructures_/Queue) - [Weave](src/_DataStructures_/Queue/weave) +- [Doubly Linked List](src/_DataStructures_/DoublyLinkedList) ### Logical Problems - [Anagrams](src/_Problems_/anagrams) @@ -52,6 +53,11 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct - [Binary Search](src/_Searching_/BinarySearch) +### Algorithms + +- [LRU Cache](src/_Algorithms_/lru-cache) + + ### Path Finder - [A\*](src/PathFinder/AStart) From 5aeb51b5eb2c4e780fb880c760a701c70fe54e86 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Mon, 7 Oct 2019 14:35:48 +0530 Subject: [PATCH 08/25] fix: More meaningful name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 48c66b20..6cb00d75 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct - [Implement Queue Using Stack](src/_DataStructures_/Stack/immitate-queue-using-stack) - [Baseball Game](src/_DataStructures_/Stack/baseball-game) - - [Minimum Stack](src/_DataStructures_/Stack/min-stack) + - [Find minimum in the Stack](src/_DataStructures_/Stack/min-stack) - [Balanced Parenthesis](src/_DataStructures_/Stack/balanced-parenthesis) - [Implement 2 Stacks using Single Array](src/_DataStructures_/Stack/2-stacks-using1-array) From 97b727bd95af2b825926ce3ca733214c115683c6 Mon Sep 17 00:00:00 2001 From: SumeetHaryani Date: Mon, 7 Oct 2019 22:53:05 +0530 Subject: [PATCH 09/25] handling fibonacci for negative numbers and 0 --- src/_Classics_/fibonacci/index.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/_Classics_/fibonacci/index.js b/src/_Classics_/fibonacci/index.js index e0852c5f..6c61bdc1 100644 --- a/src/_Classics_/fibonacci/index.js +++ b/src/_Classics_/fibonacci/index.js @@ -1,9 +1,11 @@ +//The Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21 // the algorithm has time complexity of O(n^2), very bad! function fibonacci(position) { // if position is 1 or 2, the number in fibonacci sequence will be 1 - if (position < 3) { - return 1; + if (position <= 1) { + return position; } + // else the element in fibonacci sequence will be the sum of // element at position(p) (p -1) and (p - 2) return fibonacci(position - 2) + fibonacci(position - 1); @@ -24,8 +26,8 @@ function fibonacciMemoized(index, cache) { if (cache[index]) { return cache[index]; } else { - if (index < 3) { - return 1; + if (index <=1) { + return index; } else { cache[index] = fibonacciMemoized(index - 1, cache) + @@ -41,7 +43,9 @@ function fibonacciMemoized(index, cache) { function fibonacciTabular(n) { const table = [0, 1]; - + if (n <= 1) { + return n; + } for (let i = 2; i <= n; i += 1) { table[i] = table[i - 1] + table[i - 2]; } @@ -54,4 +58,4 @@ function fibonacciTabular(n) { // console.log(`Fib normal - ${fibonacci(number)}`); // console.log('--'); // console.log(`Fib memo - ${fibonacciMemoized(number)}`); -// console.log(`Fib table - ${fibonacciTabular(number)}`); +// console.log(`Fib table - ${fibonacciTabular(number)}`); \ No newline at end of file From 572e16a098e8877bb5044b713bf02630d26d6775 Mon Sep 17 00:00:00 2001 From: ashudeshwal999 Date: Tue, 8 Oct 2019 02:53:04 +0530 Subject: [PATCH 10/25] --update : add SuffixTree --- README.md | 3 + src/_DataStructures_/SuffixTree/index.js | 121 +++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 src/_DataStructures_/SuffixTree/index.js diff --git a/README.md b/README.md index 939f0fa3..0af407ea 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,9 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct - [Queue](src/_DataStructures_/Queue) - [Weave](src/_DataStructures_/Queue/weave) +- [Suffix Tree](src/_DataStructures_/SuffixTree) + + ### Logical Problems - [Anagrams](src/_Problems_/anagrams) diff --git a/src/_DataStructures_/SuffixTree/index.js b/src/_DataStructures_/SuffixTree/index.js new file mode 100644 index 00000000..3a24308d --- /dev/null +++ b/src/_DataStructures_/SuffixTree/index.js @@ -0,0 +1,121 @@ +/* eslint-disable no-plusplus */ +/* +Implemented by watching this conceptually video: https://www.youtube.com/watch?v=VA9m_l6LpwI + +Suffix for banana are : +banana +anana +nana +ana +na +a + +Constructing a suffix tree is O(n*d) where d is length of max string + +Searching a suffix of a string is O(d) where d is length of suffix string. +If found then return the index, else return -1 + +*/ + +class Node { + constructor(value, isEnd, index) { + this.data = value; + this.isEnd = isEnd; + this.index = index; + this.next = new Map(); + } +} + +class SuffixTree { + constructor(string) { + this.head = new Node(); + this.string = string; + } + + constructSuffixTree() { + const { string } = this; + let currentString = ''; + for (let i = string.length - 1; i >= 0; i -= 1) { + currentString = string[i] + currentString; + let j = 0; + let currentNode = this.head; + while (j < currentString.length) { + if (!currentNode.next.has(currentString[j])) { + currentNode.next.set(currentString[j], new Node(currentString, true, i)); + break; + } else { + let k = 0; + const partialMatchNode = currentNode.next.get(currentString[j]); + const partialMatchString = partialMatchNode.data; + + let matchString = ''; + while (k < partialMatchString.length && j < currentString.length && partialMatchString[k] === currentString[j]) { + matchString += currentString[j]; + k++; + j++; + } + + let diffString = ''; + while (k < partialMatchString.length) { + diffString += partialMatchString[k]; + k++; + } + partialMatchNode.data = matchString; + if (diffString) { + partialMatchNode.next.set(diffString[0], new Node(diffString, true, partialMatchNode.index)); + partialMatchNode.isEnd = false; + partialMatchNode.index = null; + } + + if (partialMatchNode.next.has(currentString[j])) { + currentNode = partialMatchNode; + } else { + let nextString = ''; + while (j < currentString.length) { + nextString += currentString[j]; + j++; + } + partialMatchNode.next.set(nextString[0], new Node(nextString, true, i)); + break; + } + } + } + } + } + + findSubstring(string) { + if (!this.head.next.has(string[0])) { + return -1; + } + + let currentNode = this.head.next.get(string[0]); + let currentNodeValue = currentNode.data; + + let i = 0; let j = 0; + + while (i < string.length) { + j = 0; + while (i < string.length && j < currentNodeValue.length && string[i++] === currentNodeValue[j++]); + + if (i === string.length && j === currentNodeValue.length && currentNode.isEnd) { + return currentNode.index; + } + + if (currentNode.next.has(string[i])) { + currentNode = currentNode.next.get(string[i]); + currentNodeValue = currentNode.data; + } else { + return -1; + } + } + return -1; + } +} + +// const s = new SuffixTree('banana'); +// s.constructSuffixTree(); + +// console.log(s.findSubstring('nana')); + + +module.exports = SuffixTree; From 275917385af53147dac31990a02a196dcd428661 Mon Sep 17 00:00:00 2001 From: DaniloBarros Date: Mon, 7 Oct 2019 23:29:35 -0400 Subject: [PATCH 11/25] Add unit test to loop-in-list - Rename loop-in-list function name from `detech` to `detect` --- .../LinkedList/loop-in-list/index.js | 6 ++- .../loop-in-list/loop-in-list.test.js | 40 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/_DataStructures_/LinkedList/loop-in-list/loop-in-list.test.js diff --git a/src/_DataStructures_/LinkedList/loop-in-list/index.js b/src/_DataStructures_/LinkedList/loop-in-list/index.js index 26749191..849604b2 100644 --- a/src/_DataStructures_/LinkedList/loop-in-list/index.js +++ b/src/_DataStructures_/LinkedList/loop-in-list/index.js @@ -1,6 +1,6 @@ // Floyd’s Cycle-Finding Algorithm -function detechLoop(linkedList) { +function detectLoop(linkedList) { let slow = linkedList.getFirst(); let fast = linkedList.getFirst(); @@ -14,3 +14,7 @@ function detechLoop(linkedList) { } return false; } + +module.exports = { + detectLoop, +}; diff --git a/src/_DataStructures_/LinkedList/loop-in-list/loop-in-list.test.js b/src/_DataStructures_/LinkedList/loop-in-list/loop-in-list.test.js new file mode 100644 index 00000000..7f7afeca --- /dev/null +++ b/src/_DataStructures_/LinkedList/loop-in-list/loop-in-list.test.js @@ -0,0 +1,40 @@ +const { LinkedList } = require('../index'); +const { detectLoop } = require('.'); + +describe('Loop a LinkedList', () => { + let loopList = null; + let last = null; + beforeEach(() => { + loopList = new LinkedList(); + loopList.addAtBeginning('1'); + loopList.addAtEnd('2'); + loopList.addAtEnd('3'); + loopList.addAtEnd('4'); + loopList.addAtEnd('5'); + // Create loop in list + last = loopList.getLast(); + last.next = loopList.getFirst(); + }); + + it('Should break for empty list', () => { + loopList.delete(); + expect(() => detectLoop(loopList)).toThrow(TypeError); + }); + + it('Should return `true` when looping list', () => { + expect(detectLoop(loopList)).toEqual(true); + }); + + it('Should return `false` for non loop list', () => { + last.next = null; // remove loop in list + expect(detectLoop(loopList)).toEqual(false); + }); + + it('Should return `false` for non loop list', () => { + const list = new LinkedList(); + list.addAtBeginning('1'); + list.addAtEnd('1'); + list.addAtEnd('1'); + expect(detectLoop(list)).toEqual(false); + }); +}); From 05aa1852494dc46e8cfc7b1859fd756238647c61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B1=E2=88=82?= Date: Tue, 8 Oct 2019 12:05:06 +0530 Subject: [PATCH 12/25] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 72098182..f60a9d70 100644 --- a/README.md +++ b/README.md @@ -77,8 +77,6 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct - [Caeser Cipher](src/_Classics_/caeser_cipher) - [Fibonacci](src/_Classics_/fibonacci) ---- - ## CONTRIBUTION Guide It's great to know that you want to contribute to this repo. Thanks for taking interest. Before you start, read the following carefully. From 31c5648ba285e77e611178cc17504f7fdd273fbc Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Tue, 8 Oct 2019 12:51:27 +0530 Subject: [PATCH 13/25] refactor: folder structure --- src/_DataStructures_/{ => Trees}/SuffixTree/index.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/_DataStructures_/{ => Trees}/SuffixTree/index.js (100%) diff --git a/src/_DataStructures_/SuffixTree/index.js b/src/_DataStructures_/Trees/SuffixTree/index.js similarity index 100% rename from src/_DataStructures_/SuffixTree/index.js rename to src/_DataStructures_/Trees/SuffixTree/index.js From f32e9aaf5a036e06ea086e3e86052ef656a0f167 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Tue, 8 Oct 2019 13:27:28 +0530 Subject: [PATCH 14/25] update: BST insertion added --- src/_DataStructures_/Trees/BST/Node.js | 7 +++++ src/_DataStructures_/Trees/BST/index.js | 42 +++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/_DataStructures_/Trees/BST/Node.js create mode 100644 src/_DataStructures_/Trees/BST/index.js diff --git a/src/_DataStructures_/Trees/BST/Node.js b/src/_DataStructures_/Trees/BST/Node.js new file mode 100644 index 00000000..2b515b2a --- /dev/null +++ b/src/_DataStructures_/Trees/BST/Node.js @@ -0,0 +1,7 @@ +module.exports = class Node { + constructor(value) { + this.value = value; + this.leftChild = null; // will be a node + this.rightChild = null; // will be a node + } +}; diff --git a/src/_DataStructures_/Trees/BST/index.js b/src/_DataStructures_/Trees/BST/index.js new file mode 100644 index 00000000..2c11b29d --- /dev/null +++ b/src/_DataStructures_/Trees/BST/index.js @@ -0,0 +1,42 @@ +const Node = require('./Node'); + +class BinarySearchTree { + constructor(value) { + this.root = new Node(value); + } + + insert(root, value) { + if (root === null) { + const newNode = new Node(value); + // eslint-disable-next-line no-param-reassign + root = newNode; + return root; + } + + if (value < root.value) { + // go left + // eslint-disable-next-line no-param-reassign + root.leftChild = this.insert(root.leftChild, value); + return root; + } + if (value > root.value) { + // go right + // eslint-disable-next-line no-param-reassign + root.rightChild = this.insert(root.rightChild, value); + return root; + } + return root; + } +} + +// const bst = new BinarySearchTree(10); +// console.log(bst.root); +// bst.insert(bst.root, 12); +// bst.insert(bst.root, 9); +// bst.insert(bst.root, 19); +// bst.insert(bst.root, 11); +// bst.insert(bst.root, 6); + +// console.log(bst.root); + +module.exports = BinarySearchTree; From 7b65d6a9092437fd1b4629c606788542e02009c6 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Tue, 8 Oct 2019 13:49:02 +0530 Subject: [PATCH 15/25] update: preorder traversal --- src/_DataStructures_/Trees/BST/index.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/_DataStructures_/Trees/BST/index.js b/src/_DataStructures_/Trees/BST/index.js index 2c11b29d..23e94f41 100644 --- a/src/_DataStructures_/Trees/BST/index.js +++ b/src/_DataStructures_/Trees/BST/index.js @@ -27,6 +27,15 @@ class BinarySearchTree { } return root; } + + preorder(root) { + if (root === null) return; + // eslint-disable-next-line no-console + console.log(`${root.value} `); + + this.preorder(root.leftChild); + this.preorder(root.rightChild); + } } // const bst = new BinarySearchTree(10); @@ -39,4 +48,6 @@ class BinarySearchTree { // console.log(bst.root); +// bst.preorder(bst.root); + module.exports = BinarySearchTree; From 22787ddacac9a0ec357de4db86a59b1dbea3eb27 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Tue, 8 Oct 2019 13:52:41 +0530 Subject: [PATCH 16/25] update: return pre-order traversal as an array --- src/_DataStructures_/Trees/BST/index.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/_DataStructures_/Trees/BST/index.js b/src/_DataStructures_/Trees/BST/index.js index 23e94f41..8313943a 100644 --- a/src/_DataStructures_/Trees/BST/index.js +++ b/src/_DataStructures_/Trees/BST/index.js @@ -29,12 +29,17 @@ class BinarySearchTree { } preorder(root) { - if (root === null) return; + /** returning an array so as to make testing easy */ + let arr = []; + if (root === null) return []; // eslint-disable-next-line no-console - console.log(`${root.value} `); + arr.push(root.value); - this.preorder(root.leftChild); - this.preorder(root.rightChild); + const left = this.preorder(root.leftChild); + arr = [...arr, ...left]; + const right = this.preorder(root.rightChild); + arr = [...arr, ...right]; + return arr; } } @@ -48,6 +53,7 @@ class BinarySearchTree { // console.log(bst.root); -// bst.preorder(bst.root); +// const a = bst.preorder(bst.root); +// console.log('arr = ', a); module.exports = BinarySearchTree; From 312e43a5d85d09cdd514e81d472480a103197388 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Tue, 8 Oct 2019 13:53:53 +0530 Subject: [PATCH 17/25] cleanup --- src/_DataStructures_/Trees/BST/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_DataStructures_/Trees/BST/index.js b/src/_DataStructures_/Trees/BST/index.js index 8313943a..0e1dfed8 100644 --- a/src/_DataStructures_/Trees/BST/index.js +++ b/src/_DataStructures_/Trees/BST/index.js @@ -32,11 +32,11 @@ class BinarySearchTree { /** returning an array so as to make testing easy */ let arr = []; if (root === null) return []; - // eslint-disable-next-line no-console arr.push(root.value); const left = this.preorder(root.leftChild); arr = [...arr, ...left]; + const right = this.preorder(root.rightChild); arr = [...arr, ...right]; return arr; From 34593cbef565f7559d7d917732003217184cc96e Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Tue, 8 Oct 2019 14:07:24 +0530 Subject: [PATCH 18/25] cleanup --- src/_DataStructures_/Trees/BST/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/_DataStructures_/Trees/BST/index.js b/src/_DataStructures_/Trees/BST/index.js index 0e1dfed8..50b36889 100644 --- a/src/_DataStructures_/Trees/BST/index.js +++ b/src/_DataStructures_/Trees/BST/index.js @@ -14,13 +14,11 @@ class BinarySearchTree { } if (value < root.value) { - // go left // eslint-disable-next-line no-param-reassign root.leftChild = this.insert(root.leftChild, value); return root; } if (value > root.value) { - // go right // eslint-disable-next-line no-param-reassign root.rightChild = this.insert(root.rightChild, value); return root; From 78cb213d15e3101d7dd5b08e161844d0d8d835a6 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Tue, 8 Oct 2019 14:20:55 +0530 Subject: [PATCH 19/25] update: implementation of Inorder Traversal --- src/_DataStructures_/Trees/BST/index.js | 32 +++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/_DataStructures_/Trees/BST/index.js b/src/_DataStructures_/Trees/BST/index.js index 50b36889..af720c88 100644 --- a/src/_DataStructures_/Trees/BST/index.js +++ b/src/_DataStructures_/Trees/BST/index.js @@ -39,19 +39,37 @@ class BinarySearchTree { arr = [...arr, ...right]; return arr; } + + inorder(root) { + if (root === null) return []; + let arr = []; + const left = this.inorder(root.leftChild); + arr = [...left, ...arr]; + + // print root + arr = [...arr, root.value]; + + const right = this.inorder(root.rightChild); + arr = [...arr, ...right]; + return arr; + } } -// const bst = new BinarySearchTree(10); +// const bst = new BinarySearchTree(6); // console.log(bst.root); -// bst.insert(bst.root, 12); +// bst.insert(bst.root, 4); // bst.insert(bst.root, 9); -// bst.insert(bst.root, 19); -// bst.insert(bst.root, 11); -// bst.insert(bst.root, 6); +// bst.insert(bst.root, 2); +// bst.insert(bst.root, 5); +// bst.insert(bst.root, 8); +// bst.insert(bst.root, 12); // console.log(bst.root); -// const a = bst.preorder(bst.root); -// console.log('arr = ', a); +// const preorder = bst.preorder(bst.root); +// console.log('Preorder Traversal - ', preorder); + +// const inorder = bst.inorder(bst.root); +// console.log('Inorder Traversal - ', inorder); module.exports = BinarySearchTree; From 5fd958e63e14b35d4e76c477f3b71bfabad006e1 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Tue, 8 Oct 2019 14:26:31 +0530 Subject: [PATCH 20/25] update: added Postorder traversal --- src/_DataStructures_/Trees/BST/index.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/_DataStructures_/Trees/BST/index.js b/src/_DataStructures_/Trees/BST/index.js index af720c88..e48b9164 100644 --- a/src/_DataStructures_/Trees/BST/index.js +++ b/src/_DataStructures_/Trees/BST/index.js @@ -41,6 +41,7 @@ class BinarySearchTree { } inorder(root) { + /** left - root - right */ if (root === null) return []; let arr = []; const left = this.inorder(root.leftChild); @@ -53,6 +54,21 @@ class BinarySearchTree { arr = [...arr, ...right]; return arr; } + + postorder(root) { + /** left - right - root */ + + if (root === null) return []; + let arr = []; + + const left = this.postorder(root.leftChild); + arr = [...left, ...arr]; + + const right = this.postorder(root.rightChild); + arr = [...arr, ...right]; + + return [...arr, root.value]; + } } // const bst = new BinarySearchTree(6); @@ -72,4 +88,7 @@ class BinarySearchTree { // const inorder = bst.inorder(bst.root); // console.log('Inorder Traversal - ', inorder); +// const postorder = bst.postorder(bst.root); +// console.log('Postorder Traversal - ', postorder); + module.exports = BinarySearchTree; From 8fae46e9e674b201b7a67e143eae6cc9923a670f Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Tue, 8 Oct 2019 14:28:21 +0530 Subject: [PATCH 21/25] update: entry for trees in README --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9af03ae1..665bc09c 100644 --- a/README.md +++ b/README.md @@ -29,13 +29,16 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct - [Postfix Expression Evaluation](src/_DataStructures_/Stack/postfix-expression-evaluation) - [Remove Consecutive Repeated Digits](src/_DataStructures_/Stack/remove-consecutive-repeated-digits) - [Implement 2 Stacks using Single Array](src/_DataStructures_/Stack/2-stacks-using1-array) - - [Queue](src/_DataStructures_/Queue) + - [Weave](src/_DataStructures_/Queue/weave) - [Doubly Linked List](src/_DataStructures_/DoublyLinkedList) -- [Suffix Tree](src/_DataStructures_/SuffixTree) + +- [Trees](src/_DataStructures_/Trees) + - [Binary Search Tree](src/_DataStructures_/Trees/BST) + - [Suffix Tree](src/_DataStructures_/SuffixTree) ### Logical Problems @@ -67,7 +70,6 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct - [LRU Cache](src/_Algorithms_/lru-cache) - ### Path Finder - [A\*](src/PathFinder/AStart) From 34750133ae1ad8cb8b82c10e511fc6258eba222e Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Tue, 8 Oct 2019 15:03:36 +0530 Subject: [PATCH 22/25] update: search in BST --- src/_DataStructures_/Trees/BST/index.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/_DataStructures_/Trees/BST/index.js b/src/_DataStructures_/Trees/BST/index.js index e48b9164..0a1ad377 100644 --- a/src/_DataStructures_/Trees/BST/index.js +++ b/src/_DataStructures_/Trees/BST/index.js @@ -69,6 +69,19 @@ class BinarySearchTree { return [...arr, root.value]; } + + search(root, value) { + if (root === null) return false; + if (value === root.value) return true; + + if (value < root.value) { + return this.search(root.leftChild, value); + } + if (value > root.value) { + return this.search(root.rightChild, value); + } + return false; + } } // const bst = new BinarySearchTree(6); @@ -91,4 +104,7 @@ class BinarySearchTree { // const postorder = bst.postorder(bst.root); // console.log('Postorder Traversal - ', postorder); +// const search = 18; +// console.log(`Search for ${search}`, bst.search(bst.root, search)); + module.exports = BinarySearchTree; From 886e4fd24139008691abd335402cb4afac80851f Mon Sep 17 00:00:00 2001 From: Darwin Cahyadi Date: Tue, 8 Oct 2019 17:46:18 +0700 Subject: [PATCH 23/25] add test smallest number --- .../get-smallest-common-number.test.js | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/_Problems_/get-smallest-common-number/get-smallest-common-number.test.js diff --git a/src/_Problems_/get-smallest-common-number/get-smallest-common-number.test.js b/src/_Problems_/get-smallest-common-number/get-smallest-common-number.test.js new file mode 100644 index 00000000..34c2b171 --- /dev/null +++ b/src/_Problems_/get-smallest-common-number/get-smallest-common-number.test.js @@ -0,0 +1,24 @@ +const { getSmallestCommonNumber } = require('.'); + +describe('Get common smallest number between two integer arrays', () => { + it('Should return -1 when both has empty array', () => { + const arr1 = []; + const arr2 = []; + + expect(getSmallestCommonNumber(arr1, arr2)).toEqual(-1); + }); + + it('Should return -1 when no common between two integer arrays', () => { + const arr1 = [1, 3, 5]; + const arr2 = [2, 4, 6]; + + expect(getSmallestCommonNumber(arr1, arr2)).toEqual(-1); + }); + + it('Should return common smallest number between two integer arrays', () => { + const arr1 = [2, 3]; + const arr2 = [2, 5, 7]; + + expect(getSmallestCommonNumber(arr1, arr2)).toEqual(2); + }); +}); From 0256f44ea5d6f1e2d502fc8d022d254d1ff8c9ec Mon Sep 17 00:00:00 2001 From: Darwin Cahyadi Date: Tue, 8 Oct 2019 17:53:42 +0700 Subject: [PATCH 24/25] add new scenario --- .../get-smallest-common-number.test.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/_Problems_/get-smallest-common-number/get-smallest-common-number.test.js b/src/_Problems_/get-smallest-common-number/get-smallest-common-number.test.js index 34c2b171..a5436caa 100644 --- a/src/_Problems_/get-smallest-common-number/get-smallest-common-number.test.js +++ b/src/_Problems_/get-smallest-common-number/get-smallest-common-number.test.js @@ -15,7 +15,14 @@ describe('Get common smallest number between two integer arrays', () => { expect(getSmallestCommonNumber(arr1, arr2)).toEqual(-1); }); - it('Should return common smallest number between two integer arrays', () => { + it('Should return common smallest number between unsorted two integer arrays', () => { + const arr1 = [-10, 3]; + const arr2 = [2, -10, 7]; + + expect(getSmallestCommonNumber(arr1, arr2)).toEqual(-10); + }); + + it('Should return common smallest number between sorted two integer arrays', () => { const arr1 = [2, 3]; const arr2 = [2, 5, 7]; From b3139d7e10592cb32625bf30b010ccb1f2298cb9 Mon Sep 17 00:00:00 2001 From: SumeetHaryani Date: Tue, 8 Oct 2019 21:32:23 +0530 Subject: [PATCH 25/25] fix fibonacci problem for negative numbers --- src/_Classics_/fibonacci/index.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/_Classics_/fibonacci/index.js b/src/_Classics_/fibonacci/index.js index 6c61bdc1..979fb5c8 100644 --- a/src/_Classics_/fibonacci/index.js +++ b/src/_Classics_/fibonacci/index.js @@ -2,8 +2,10 @@ // the algorithm has time complexity of O(n^2), very bad! function fibonacci(position) { // if position is 1 or 2, the number in fibonacci sequence will be 1 - if (position <= 1) { + if (position === 1 || position === 0) { return position; + } else if (position < 0) { + throw new Error('Invalid Position'); } // else the element in fibonacci sequence will be the sum of @@ -26,8 +28,11 @@ function fibonacciMemoized(index, cache) { if (cache[index]) { return cache[index]; } else { - if (index <=1) { + if (index === 1 || index === 0) { return index; + } else if (index < 0) { + throw new Error('Invalid Position'); + } else { cache[index] = fibonacciMemoized(index - 1, cache) + @@ -43,8 +48,10 @@ function fibonacciMemoized(index, cache) { function fibonacciTabular(n) { const table = [0, 1]; - if (n <= 1) { + if (n === 1 || n === 0) { return n; + } else if (n < 0) { + throw new Error('Invalid Position'); } for (let i = 2; i <= n; i += 1) { table[i] = table[i - 1] + table[i - 2];