Skip to content

Commit 599263d

Browse files
committedOct 17, 2019
Merge branch 'master' of github.com:knaxus/problem-solving-javascript into problems
2 parents 2f39c26 + bc95e85 commit 599263d

File tree

13 files changed

+388
-4
lines changed

13 files changed

+388
-4
lines changed
 

‎README.md

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct
2929
- [Postfix Expression Evaluation](src/_DataStructures_/Stack/postfix-expression-evaluation)
3030
- [Remove Consecutive Repeated Digits](src/_DataStructures_/Stack/remove-consecutive-repeated-digits)
3131
- [Implement 2 Stacks using Single Array](src/_DataStructures_/Stack/2-stacks-using1-array)
32+
- [Sort a Stack](src/_DataStructures_/Stack/sort-a-stack)
33+
3234

3335
- [Queue](src/_DataStructures_/Queue)
3436

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* Sort a stack with the help of a temporary stack.
3+
* Input:[1,10,21,3,9,-11,32]
4+
* Output:[32,21,10,9,3,1,-11]
5+
* Time Complexity:O(N^2)
6+
*/
7+
const Stack = require('../index');
8+
9+
function sortStack(stack) {
10+
const tempStack = new Stack();
11+
while (!stack.isEmpty()) {
12+
//pop the first element from stack
13+
let temp = stack.pop();
14+
//for ascending order (tempStack.peek() < temp)
15+
while (!tempStack.isEmpty() && tempStack.peek() > temp) {
16+
stack.push(tempStack.pop());
17+
}
18+
//push the first element(temp) onto tempStack if tempStack.peek()<temp
19+
tempStack.push(temp);
20+
}
21+
return tempStack;
22+
}
23+
/*
24+
const s = new Stack();
25+
26+
s.push(1);
27+
s.push(10);
28+
s.push(21);
29+
s.push(3);
30+
s.push(9);
31+
s.push(-11);
32+
s.push(32);
33+
console.log(s.data);
34+
const s1 = sortStack(s);
35+
console.log(s1.data);
36+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const BST = require('.');
2+
3+
describe('Data Structure : Binary Search Tree', () => {
4+
it('Should be class', () => {
5+
expect(typeof BST.prototype.constructor).toEqual('function');
6+
});
7+
8+
describe('Binary Search Tree API', () => {
9+
let bst = null;
10+
11+
beforeEach(() => {
12+
bst = new BST(5);
13+
});
14+
15+
it('Should delete() an element from Binary Search Tree', () => {
16+
bst.add(4);
17+
bst.add(9);
18+
bst.add(2);
19+
bst.delete(bst.root, 4);
20+
expect(bst.traverseInorder()).toEqual([2, 5, 9]);
21+
bst.delete(bst.root, 2);
22+
expect(bst.traverseInorder()).toEqual([5, 9]);
23+
});
24+
});
25+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
const BinarySearchTree = require('./index');
2+
3+
describe('Binary Search Tree', () => {
4+
let bst;
5+
let rootsLeftChild;
6+
let rootsRightChild;
7+
let rootsLeftChildsLeftChild;
8+
let rootsLeftChildsRightChild;
9+
let rootsRightChildsLeftChild;
10+
let rootsRightChildsRightChild;
11+
12+
describe('Creates a binary search tree', () => {
13+
it('should create a bst with root 100', () => {
14+
bst = new BinarySearchTree(100);
15+
expect(bst.root.value).toEqual(100);
16+
});
17+
18+
it('should add element 20 to the left of root node', () => {
19+
bst.add(20);
20+
rootsLeftChild = bst.root.leftChild;
21+
expect(rootsLeftChild.value).toEqual(20);
22+
});
23+
24+
it('should add element 500 to the right of root node', () => {
25+
bst.add(500);
26+
rootsRightChild = bst.root.rightChild;
27+
expect(rootsRightChild.value).toEqual(500);
28+
});
29+
30+
it('should add element 10 to the left of root"s left child', () => {
31+
bst.add(10);
32+
rootsLeftChildsLeftChild = bst.root.leftChild.leftChild;
33+
expect(rootsLeftChildsLeftChild.value).toEqual(10);
34+
});
35+
36+
it('should add element 30 to the right of root"s left child', () => {
37+
bst.add(30);
38+
rootsLeftChildsRightChild = bst.root.leftChild.rightChild;
39+
expect(rootsLeftChildsRightChild.value).toEqual(30);
40+
});
41+
42+
it('should add element 400 to the left of root"s right child', () => {
43+
bst.add(400);
44+
rootsRightChildsLeftChild = bst.root.rightChild.leftChild;
45+
expect(rootsRightChildsLeftChild.value).toEqual(400);
46+
});
47+
48+
it('should add element 600 to the right of root"s right child', () => {
49+
bst.add(600);
50+
rootsRightChildsRightChild = bst.root.rightChild.rightChild;
51+
expect(rootsRightChildsRightChild.value).toEqual(600);
52+
});
53+
});
54+
55+
describe('Check insertion was as expected', () => {
56+
it('Inorder traversal of the created bst should be [ 10, 20, 30, 100, 400, 500, 600 ]', () => {
57+
expect(bst.traverseInorder()).toEqual([10, 20, 30, 100, 400, 500, 600]);
58+
});
59+
60+
it('Preorder traversal of the created bst should be [ 100, 20, 10, 30, 500, 400, 600 ]', () => {
61+
expect(bst.traversePreorder()).toEqual([100, 20, 10, 30, 500, 400, 600]);
62+
});
63+
64+
it('Postorder traversal of the created bst should be [ 10, 30, 20, 400, 600, 500, 100 ]', () => {
65+
expect(bst.traversePostorder()).toEqual([10, 30, 20, 400, 600, 500, 100]);
66+
});
67+
});
68+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Lowest Common Ancestor in a Binary Search Tree.
3+
*
4+
* Given values of two values n1 and n2 in a Binary Search Tree, find the Lowest Common Ancestor (LCA). You may assume that both the values exist in the tree.
5+
*/
6+
7+
function lca(node, n1, n2) {
8+
if (node == null)
9+
return null;
10+
11+
// If both n1 and n2 are smaller than root, then LCA lies in left
12+
if (node.value > n1 && node.value > n2)
13+
return lca(node.leftChild, n1, n2);
14+
15+
// If both n1 and n2 are greater than root, then LCA lies in right
16+
if (node.value < n1 && node.value < n2)
17+
return lca(node.rightChild, n1, n2);
18+
19+
return node;
20+
}
21+
22+
module.exports = {
23+
lca,
24+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const { lca } = require('.');
2+
const BinarySearchTree = require('../index');
3+
4+
// Quick JSON equivalent
5+
// {"left":{"left":{"data":4},"right":{"left":{"data":10},"right":{"data":14},"data":12},"data":8},"right":{"data":22},"data":20}
6+
7+
describe('LCA', () => {
8+
9+
let bst = new BinarySearchTree(20);
10+
bst.add(22);
11+
bst.add(8);
12+
bst.add(12);
13+
bst.add(4);
14+
bst.add(14);
15+
bst.add(10);
16+
17+
it('Should return 12', () => {
18+
expect(lca(bst.root, 10, 14).value).toEqual(12);
19+
});
20+
21+
it('Should return 8', () => {
22+
expect(lca(bst.root, 14, 8).value).toEqual(8);
23+
});
24+
25+
it('Should return 20', () => {
26+
expect(lca(bst.root, 10, 22).value).toEqual(20);
27+
});
28+
});

‎src/_DataStructures_/Trees/SuffixTree/index.js

+30-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* eslint-disable max-len */
2+
/* eslint-disable no-restricted-syntax */
13
/* eslint-disable no-plusplus */
24
/*
35
Implemented by watching this conceptually video: https://www.youtube.com/watch?v=VA9m_l6LpwI
@@ -17,6 +19,7 @@ If found then return the index, else return -1
1719
1820
*/
1921

22+
const alphabets = 'abcdefghijklmnopqrstuvwxyz';
2023
class Node {
2124
constructor(value, isEnd, index) {
2225
this.data = value;
@@ -41,7 +44,12 @@ class SuffixTree {
4144
let currentNode = this.head;
4245
while (j < currentString.length) {
4346
if (!currentNode.next.has(currentString[j])) {
44-
currentNode.next.set(currentString[j], new Node(currentString, true, i));
47+
let nextString = '';
48+
while (j < currentString.length) {
49+
nextString += currentString[j];
50+
j++;
51+
}
52+
currentNode.next.set(nextString[0], new Node(nextString, true, i));
4553
break;
4654
} else {
4755
let k = 0;
@@ -60,9 +68,20 @@ class SuffixTree {
6068
diffString += partialMatchString[k];
6169
k++;
6270
}
71+
6372
partialMatchNode.data = matchString;
6473
if (diffString) {
65-
partialMatchNode.next.set(diffString[0], new Node(diffString, true, partialMatchNode.index));
74+
const oldMap = partialMatchNode.next;
75+
const newNode = new Node(diffString, partialMatchNode.isEnd, partialMatchNode.index);
76+
const alphabetsArray = alphabets.split('');
77+
78+
for (const char of alphabetsArray) {
79+
if (oldMap.has(char)) {
80+
newNode.next.set(char, oldMap.get(char));
81+
}
82+
}
83+
partialMatchNode.next = new Map();
84+
partialMatchNode.next.set(diffString[0], newNode);
6685
partialMatchNode.isEnd = false;
6786
partialMatchNode.index = null;
6887
}
@@ -112,10 +131,17 @@ class SuffixTree {
112131
}
113132
}
114133

115-
// const s = new SuffixTree('banana');
134+
// const st = 'asdjkxhcjbzdmnsjakdhasdbajw';
135+
// const s = new SuffixTree(st);
116136
// s.constructSuffixTree();
137+
// // console.log(s.head.next);
117138

118-
// console.log(s.findSubstring('nana'));
119139

140+
// for (let i = 0; i < st.length; i++) {
141+
// const e = st.substring(i);
142+
// if (s.findSubstring(e) !== i) {
143+
// console.log(e, i, s.findSubstring(e));
144+
// }
145+
// }
120146

121147
module.exports = SuffixTree;

‎src/_Problems_/factorial/index.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
function factorial(num) {
2+
if (num === 1) return num;
3+
else return num * factorial(num - 1);
4+
}
5+
6+
module.exports = {
7+
factorial,
8+
};
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const { factorial } = require('.');
2+
3+
describe('Factorial', () => {
4+
it('Should return 24', () => {
5+
expect(factorial(4)).toEqual(24);
6+
});
7+
8+
it('Should return 1', () => {
9+
expect(factorial(1)).toEqual(1);
10+
});
11+
12+
it('Should return 120', () => {
13+
expect(factorial(5)).toEqual(120);
14+
});
15+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const { jumpSearch, jumpSearchRecursive } = require('.');
2+
3+
describe('Jump Search', () => {
4+
    const array = [1, 2, 3, 4, 5, 6, 7, 8];
5+
    describe('When element to find is at 1st position ', () => {
6+
        it('Jump search', () => {
7+
          expect(jumpSearch(array, 1)).toEqual(0);
8+
        });
9+
      });
10+
    describe('When element to find is at last position ', () => {
11+
        it('Jump search', () => {
12+
          expect(jumpSearch(array, 7)).toEqual(6);
13+
        });
14+
      });
15+
    describe('When element to find is at random position ', () => {
16+
        it('Jump search', () => {
17+
          expect(jumpSearch(array, 3)).toEqual(2);
18+
        });
19+
      });
20+
});

‎src/_Searching_/JumpSearch/index.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Note: Array must be sorted for jump search
3+
* Complexity:
4+
* Worst case time complexity: O(√N)
5+
* Average case time complexity: O(√N)
6+
* Best case time complexity: O(1)
7+
* Space complexity: O(1)
8+
*/
9+
function jumpSearch(arr, key) {
10+
const n = arr.length;
11+
const jump = Math.floor(Math.sqrt(n));
12+
let step = jump;
13+
14+
let prev = 0;
15+
16+
while(arr[Math.min(step, n) - 1] < key) {
17+
prev = step;
18+
step += jump;
19+
if (prev >= n)
20+
return null;
21+
}
22+
23+
while(arr[prev] < key) {
24+
prev++;
25+
26+
if (prev == Math.min(step, n))
27+
return null;
28+
}
29+
30+
if (arr[prev] == key)
31+
return prev;
32+
33+
return null;
34+
}
35+
36+
module.exports = {
37+
jumpSearch,
38+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const { ternarySearch, ternarySearchRecursive } = require('.');
2+
3+
describe('Ternary Search', () => {
4+
const array = [1, 2, 3, 4, 5, 6, 7, 8];
5+
const low = 0;
6+
const high = array.length - 1;
7+
8+
describe('When element to find is at 1st position ', () => {
9+
it('Ternary search with Loop', () => {
10+
expect(ternarySearch(array, 1)).toEqual(0);
11+
});
12+
it('Ternary serach with recursion', () => {
13+
expect(ternarySearchRecursive(array, low, high, 1)).toEqual(0);
14+
});
15+
});
16+
describe('When element to find is at last position ', () => {
17+
it('Ternary search with Loop', () => {
18+
expect(ternarySearch(array, 8)).toEqual(7);
19+
});
20+
it('Ternary serach with recursion', () => {
21+
expect(ternarySearchRecursive(array, low, high, 8)).toEqual(7);
22+
});
23+
});
24+
describe('When element to find is at random position ', () => {
25+
it('Ternary search with Loop', () => {
26+
expect(ternarySearch(array, 3)).toEqual(2);
27+
});
28+
it('Ternary serach with recursion', () => {
29+
expect(ternarySearchRecursive(array, low, high, 4)).toEqual(3);
30+
});
31+
});
32+
describe('When element to find is no present in array ', () => {
33+
it('Ternary search with Loop', () => {
34+
expect(ternarySearch(array, 10)).toEqual(null);
35+
});
36+
it('Ternary serach with recursion', () => {
37+
expect(ternarySearchRecursive(array, low, high, 10)).toEqual(null);
38+
});
39+
});
40+
41+
});

0 commit comments

Comments
 (0)
Please sign in to comment.