diff --git a/README.md b/README.md
index 665bc09c..fd888d40 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,7 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct
- [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)
@@ -37,7 +38,12 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct
- [Doubly Linked List](src/_DataStructures_/DoublyLinkedList)
- [Trees](src/_DataStructures_/Trees)
- - [Binary Search Tree](src/_DataStructures_/Trees/BST)
+ - [Binary Search Tree](src/_DataStructures_/Trees/BinarySearchTree)
+ - [Find kth maximum in a BinarySearchTree](src/_DataStructures_/Trees/BinarySearchTree/find-kth-max)
+ - [Find kth minimum in a BinarySearchTree](src/_DataStructures_/Trees/BinarySearchTree/find-kth-min)
+ - [Find Ancestors of a Node](src/_DataStructures_/Trees/BinarySearchTree/find-ancestors)
+ - [Find Height of BST](src/_DataStructures_/Trees/BinarySearchTree/height-of-bst)
+ - [Find k Nodes from Root of BST](src/_DataStructures_/Trees/BinarySearchTree/find-k-nodes-from-root)
- [Suffix Tree](src/_DataStructures_/SuffixTree)
### Logical Problems
@@ -50,7 +56,7 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct
- [FizzBuzz](src/_Problems_/fizzbuzz)
- [String Permutaions](src/_Problems_/get-string-permutations)
- [Get Subsequence](src/_Problems_/get_subsequence)
-- [Get Maze Path](src/_Problems_/get_subsequence)
+- [Get Maze Path](src/_Problems_/get-mazePath)
- [Get longest consecutive 1s](src/_Problems_/max-consecutive-1s)
- [Get Max Char](src/_Problems_/maxchar)
- [Get Smallest Common Number](src/_Problems_/get-smallest-common-number)
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];
diff --git a/src/_DataStructures_/DoublyLinkedList/index.js b/src/_DataStructures_/DoublyLinkedList/index.js
index 522924b9..40d6bf3e 100644
--- a/src/_DataStructures_/DoublyLinkedList/index.js
+++ b/src/_DataStructures_/DoublyLinkedList/index.js
@@ -55,10 +55,12 @@ class DoublyLinkedList {
display() {
let address = this.head.next;
+ let addresses = []
while (address !== this.tail) {
- console.log(address.data);
+ addresses.push(address.data)
address = address.next;
}
+ return addresses
}
}
diff --git a/src/_DataStructures_/Queue/index.js b/src/_DataStructures_/Queue/index.js
index 99d1861c..d51bcab0 100644
--- a/src/_DataStructures_/Queue/index.js
+++ b/src/_DataStructures_/Queue/index.js
@@ -17,4 +17,4 @@ class Queue {
}
}
-module.exports = Queue;
+module.exports = Queue;
\ No newline at end of file
diff --git a/src/_DataStructures_/Stack/postfix-expression-evaluation/index.js b/src/_DataStructures_/Stack/postfix-expression-evaluation/index.js
index 3441abb5..9db393e9 100644
--- a/src/_DataStructures_/Stack/postfix-expression-evaluation/index.js
+++ b/src/_DataStructures_/Stack/postfix-expression-evaluation/index.js
@@ -15,9 +15,9 @@ function evaluatePostfixExpression(expression) {
s.push(Number(char));
} else {
// if char is an operator then pop two elements from stack, evaluate them accordingly based on operator.
- //push the result to stack
+ //push the result to stack
let val1 = s.pop();
- let val2 = s.pop()
+ let val2 = s.pop();
switch (char) {
case '+':
s.push(val2 + val1);
@@ -38,3 +38,7 @@ function evaluatePostfixExpression(expression) {
//pop the value of postfix expression
return s.pop();
}
+
+module.exports = {
+ evaluatePostfixExpression,
+};
diff --git a/src/_DataStructures_/Stack/postfix-expression-evaluation/postfix-expression-evaluation.test.js b/src/_DataStructures_/Stack/postfix-expression-evaluation/postfix-expression-evaluation.test.js
new file mode 100644
index 00000000..47e0de42
--- /dev/null
+++ b/src/_DataStructures_/Stack/postfix-expression-evaluation/postfix-expression-evaluation.test.js
@@ -0,0 +1,55 @@
+const { evaluatePostfixExpression } = require('.');
+
+describe('Postfix expression evaluation', function () {
+ it('should be a function', function () {
+ expect(typeof evaluatePostfixExpression).toEqual('function');
+ });
+
+ it('should return a number', function () {
+ const expression = '11+';
+
+ expect(typeof evaluatePostfixExpression(expression)).toEqual('number')
+ });
+
+ it('should handle addition', function () {
+ const expression = '23+';
+ const expected = 5;
+
+ expect(evaluatePostfixExpression(expression)).toEqual(expected);
+ });
+
+ it('should handle subtraction', function () {
+ const expression = '54-';
+ const expected = 1;
+
+ expect(evaluatePostfixExpression(expression)).toEqual(expected);
+ });
+
+ it('should handle multiplication', function () {
+ const expression = '34*';
+ const expected = 12;
+
+ expect(evaluatePostfixExpression(expression)).toEqual(expected);
+ });
+
+ it('should handle division', function () {
+ const expression = '62/';
+ const expected = 3;
+
+ expect(evaluatePostfixExpression(expression)).toEqual(expected);
+ });
+
+ it('should handle negative numbers', function () {
+ const expression = '25-';
+ const expected = -3;
+
+ expect(evaluatePostfixExpression(expression)).toEqual(expected);
+ });
+
+ it('should handle multiple operators', function () {
+ const expression = '123*+';
+ const expected = 7;
+
+ expect(evaluatePostfixExpression(expression)).toEqual(expected);
+ });
+});
diff --git a/src/_DataStructures_/Trees/BST/Node.js b/src/_DataStructures_/Trees/BinarySearchTree/Node.js
similarity index 100%
rename from src/_DataStructures_/Trees/BST/Node.js
rename to src/_DataStructures_/Trees/BinarySearchTree/Node.js
diff --git a/src/_DataStructures_/Trees/BinarySearchTree/find-ancestors/index.js b/src/_DataStructures_/Trees/BinarySearchTree/find-ancestors/index.js
new file mode 100644
index 00000000..4ccea5f9
--- /dev/null
+++ b/src/_DataStructures_/Trees/BinarySearchTree/find-ancestors/index.js
@@ -0,0 +1,49 @@
+// eslint-disable-next-line no-unused-vars
+const BST = require('../index');
+
+/** You should go through this conversation here:
+ * https://github.com/knaxus/problem-solving-javascript/pull/63
+ */
+
+function findAncestors(root, value) {
+ /**
+ * search the given node and meanwhile
+ * keep pushing the visited nodes
+ */
+ if (root === null) return false;
+
+ if (value < root.value) {
+ const left = findAncestors(root.leftChild, value);
+ if (left) {
+ return [...left, root.value];
+ }
+ return false;
+ }
+
+ if (value > root.value) {
+ const right = findAncestors(root.rightChild, value);
+ if (right) {
+ return [...right, root.value];
+ }
+ return false;
+ }
+
+ if (value === root.value) return [];
+ return false;
+}
+
+// create a BST
+// const myBST = new BST(6);
+// myBST.add(4);
+// myBST.add(9);
+// myBST.add(2);
+// myBST.add(5);
+// myBST.add(14);
+// myBST.add(8);
+// myBST.add(12);
+// myBST.add(10);
+
+// console.log(findAncestors(myBST.root, 10));
+// console.log(findAncestors(myBST.root, 101));
+
+module.exports = findAncestors;
diff --git a/src/_DataStructures_/Trees/BinarySearchTree/find-k-nodes-from-root/index.js b/src/_DataStructures_/Trees/BinarySearchTree/find-k-nodes-from-root/index.js
new file mode 100644
index 00000000..25aa70d1
--- /dev/null
+++ b/src/_DataStructures_/Trees/BinarySearchTree/find-k-nodes-from-root/index.js
@@ -0,0 +1,33 @@
+// eslint-disable-next-line no-unused-vars
+const BST = require('../index');
+
+function findKNodes(root, k) {
+ let arr = [];
+
+ if (root === null) return [];
+ if (k === 0) return [...arr, root.value];
+
+ const left = findKNodes(root.leftChild, k - 1);
+ arr = [...arr, ...left];
+
+ const right = findKNodes(root.rightChild, k - 1);
+ arr = [...arr, ...right];
+ return arr;
+}
+
+// create a BST
+// const myBST = new BST(6);
+
+// myBST.add(2);
+// myBST.add(19);
+// myBST.add(14);
+// myBST.add(8);
+// myBST.add(5);
+// myBST.add(12);
+// myBST.add(33);
+// myBST.add(52);
+// myBST.add(1);
+
+// console.log(findKNodes(myBST.root, 2));
+
+module.exports = findKNodes;
diff --git a/src/_DataStructures_/Trees/BinarySearchTree/find-kth-max/index.js b/src/_DataStructures_/Trees/BinarySearchTree/find-kth-max/index.js
new file mode 100644
index 00000000..21ba18f7
--- /dev/null
+++ b/src/_DataStructures_/Trees/BinarySearchTree/find-kth-max/index.js
@@ -0,0 +1,39 @@
+// eslint-disable-next-line no-unused-vars
+const BST = require('../index');
+
+// Inorder traversal returns a sorted array
+function inOrderTraversal(root) {
+ if (root === null) return [];
+ let arr = [];
+ // traverse left
+ const left = inOrderTraversal(root.leftChild);
+ arr = [...left, root.value];
+ const right = inOrderTraversal(root.rightChild);
+ return [...arr, ...right];
+}
+
+function findKthMax(rootNode, k) {
+ const arr = inOrderTraversal(rootNode);
+ if (k <= 0 || k > arr.lenth) {
+ throw new Error('Invalid value for K');
+ }
+ return arr[arr.length - k];
+}
+
+// // create a BST
+// const myBST = new BST(6);
+
+// myBST.add(2);
+// myBST.add(19);
+// myBST.add(14);
+// myBST.add(8);
+// myBST.add(5);
+// myBST.add(12);
+// myBST.add(33);
+// myBST.add(52);
+// myBST.add(1);
+
+// // find 3rd max
+// console.log(findKthMax(myBST.root, 3));
+
+module.exports = findKthMax;
diff --git a/src/_DataStructures_/Trees/BinarySearchTree/find-kth-min/index.js b/src/_DataStructures_/Trees/BinarySearchTree/find-kth-min/index.js
new file mode 100644
index 00000000..ad18cdea
--- /dev/null
+++ b/src/_DataStructures_/Trees/BinarySearchTree/find-kth-min/index.js
@@ -0,0 +1,39 @@
+// eslint-disable-next-line no-unused-vars
+const BST = require('../index');
+
+// Inorder traversal returns a sorted array
+function inOrderTraversal(root) {
+ if (root === null) return [];
+ let arr = [];
+ // traverse left
+ const left = inOrderTraversal(root.leftChild);
+ arr = [...left, root.value];
+ const right = inOrderTraversal(root.rightChild);
+ return [...arr, ...right];
+}
+
+function findKthMin(rootNode, k) {
+ const arr = inOrderTraversal(rootNode);
+ if (k <= 0 || k > arr.lenth) {
+ throw new Error('Invalid value for K');
+ }
+ return arr[k - 1];
+}
+
+// // create a BST
+// const myBST = new BST(6);
+
+// myBST.add(2);
+// myBST.add(19);
+// myBST.add(14);
+// myBST.add(8);
+// myBST.add(5);
+// myBST.add(12);
+// myBST.add(33);
+// myBST.add(52);
+// myBST.add(1);
+// myBST.add(0);
+
+// console.log(findKthMin(myBST.root, 3));
+
+module.exports = findKthMin;
diff --git a/src/_DataStructures_/Trees/BinarySearchTree/height-of-bst/index.js b/src/_DataStructures_/Trees/BinarySearchTree/height-of-bst/index.js
new file mode 100644
index 00000000..ad4f1ee7
--- /dev/null
+++ b/src/_DataStructures_/Trees/BinarySearchTree/height-of-bst/index.js
@@ -0,0 +1,33 @@
+// eslint-disable-next-line no-unused-vars
+const BST = require('../index');
+
+function findHeightOfBST(root) {
+ let leftHeight = 0;
+ let rightHeight = 0;
+
+ if (root === null) return 0;
+ leftHeight = findHeightOfBST(root.leftChild);
+ rightHeight = findHeightOfBST(root.rightChild);
+
+ if (leftHeight > rightHeight) {
+ return leftHeight + 1;
+ }
+ return rightHeight + 1;
+}
+
+// create a BST
+// const myBST = new BST(6);
+// myBST.add(4);
+// myBST.add(9);
+// myBST.add(2);
+// myBST.add(5);
+// myBST.add(14);
+// myBST.add(8);
+// myBST.add(12);
+// myBST.add(10);
+
+// // console.log(myBST.root);
+// console.log(myBST.traversePreorder());
+// console.log(findHeightOfBST(myBST.root));
+
+module.exports = findHeightOfBST;
diff --git a/src/_DataStructures_/Trees/BST/index.js b/src/_DataStructures_/Trees/BinarySearchTree/index.js
similarity index 100%
rename from src/_DataStructures_/Trees/BST/index.js
rename to src/_DataStructures_/Trees/BinarySearchTree/index.js
diff --git a/src/_Problems_/get-mazePath/get-mazePath.test.js b/src/_Problems_/get-mazePath/get-mazePath.test.js
new file mode 100644
index 00000000..b30f50af
--- /dev/null
+++ b/src/_Problems_/get-mazePath/get-mazePath.test.js
@@ -0,0 +1,41 @@
+const { getMazePath } = require('.');
+
+describe('Get maze path', () => {
+ it('returns all possible solutions for a 2x2 grid', () => {
+ const expectedSolutions = ['HHVV', 'HVHV', 'HVVH', 'VHHV', 'VHVH', 'VVHH'];
+
+ expect(getMazePath(0, 0, 2, 2)).toEqual(expectedSolutions);
+ });
+
+ it('returns an even amount of horizontal and vertical movements', () => {
+ const solutions = getMazePath(0, 0, 3, 3);
+
+ solutions.forEach(solution => {
+ expect(solution.length).toEqual(6);
+
+ expect(solution.match(/H/g).length).toEqual(3);
+ expect(solution.match(/V/g).length).toEqual(3);
+ });
+ });
+
+ it('returns the expected number of solutions based on given grids', () => {
+ expect(getMazePath(0, 0, 1, 1).length).toEqual(2);
+ expect(getMazePath(0, 0, 2, 2).length).toEqual(6);
+ expect(getMazePath(0, 0, 3, 3).length).toEqual(20);
+ expect(getMazePath(0, 0, 4, 4).length).toEqual(70);
+
+ expect(getMazePath(1, 1, 4, 4).length).toEqual(20);
+ });
+
+ it('returns an empty array when the start and end coordinates are equal', () => {
+ const solutions = getMazePath(2, 2, 2, 2);
+
+ expect(solutions).toEqual(['']);
+ });
+
+ it('returns an empty array when the start coordinates are greater than the end coordinates', () => {
+ const solutions = getMazePath(2, 2, 1, 1);
+
+ expect(solutions).toEqual([]);
+ });
+});
\ No newline at end of file
diff --git a/src/_Problems_/get-mazePath/index.js b/src/_Problems_/get-mazePath/index.js
index 99aead53..cff29bee 100644
--- a/src/_Problems_/get-mazePath/index.js
+++ b/src/_Problems_/get-mazePath/index.js
@@ -7,10 +7,7 @@
// --->> er = end row
// --->> ec = end column
-
-
-
-let getMazePath = (cr, cc, er, ec) => {
+const getMazePath = (cr, cc, er, ec) => {
if(cr == er && cc == ec) { //============POSITIVE BASE CASE===========
let br = [];
br.push('');
@@ -37,6 +34,4 @@ let getMazePath = (cr, cc, er, ec) => {
return myResult;
}
-
-let path = getMazePath(0, 0, 2, 2);
-console.log(path);
\ No newline at end of file
+module.exports = { getMazePath };
\ No newline at end of file