Skip to content

Commit 421200c

Browse files
committed
Merge branch 'master' of github.com:knaxus/problem-solving-javascript into problems
2 parents 5aeb51b + 05aa185 commit 421200c

File tree

9 files changed

+388
-9
lines changed

9 files changed

+388
-9
lines changed

README.md

+11-2
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,17 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct
2626
- [Baseball Game](src/_DataStructures_/Stack/baseball-game)
2727
- [Find minimum in the Stack](src/_DataStructures_/Stack/min-stack)
2828
- [Balanced Parenthesis](src/_DataStructures_/Stack/balanced-parenthesis)
29+
- [Postfix Expression Evaluation](src/_DataStructures_/Stack/postfix-expression-evaluation)
30+
- [Remove Consecutive Repeated Digits](src/_DataStructures_/Stack/remove-consecutive-repeated-digits)
2931
- [Implement 2 Stacks using Single Array](src/_DataStructures_/Stack/2-stacks-using1-array)
32+
3033

3134
- [Queue](src/_DataStructures_/Queue)
3235
- [Weave](src/_DataStructures_/Queue/weave)
3336

37+
- [Doubly Linked List](src/_DataStructures_/DoublyLinkedList)
38+
- [Suffix Tree](src/_DataStructures_/SuffixTree)
39+
3440
### Logical Problems
3541

3642
- [Anagrams](src/_Problems_/anagrams)
@@ -57,6 +63,11 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct
5763

5864
- [Binary Search](src/_Searching_/BinarySearch)
5965

66+
### Algorithms
67+
68+
- [LRU Cache](src/_Algorithms_/lru-cache)
69+
70+
6071
### Path Finder
6172

6273
- [A\*](src/PathFinder/AStart)
@@ -66,8 +77,6 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct
6677
- [Caeser Cipher](src/_Classics_/caeser_cipher)
6778
- [Fibonacci](src/_Classics_/fibonacci)
6879

69-
---
70-
7180
## CONTRIBUTION Guide
7281

7382
It's great to know that you want to contribute to this repo. Thanks for taking interest. Before you start, read the following carefully.

src/_Algorithms_/lru-cache/index.js

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
Least recently used (LRU) - cache implementation
3+
4+
get(key) – Get the value (will always be positive) of the key if the key exists in the cache, otherwise return false.
5+
Complexity: O(1)
6+
7+
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.
8+
Complexity: O(1)
9+
*/
10+
11+
const DoublyLinkedList = require('../../_DataStructures_/DoublyLinkedList/index');
12+
13+
class LRUCache {
14+
constructor(n) {
15+
this.size = n;
16+
this.map = new Map();
17+
this.list = new DoublyLinkedList();
18+
}
19+
20+
// this method will work in O(1)
21+
set(key, value) {
22+
const data = {
23+
key,
24+
value,
25+
};
26+
if (!this.map.has(key)) {
27+
this.list.addAtBeginning(data);
28+
this.map.set(key, this.list.head.next);
29+
30+
if (this.list.length() > this.size) {
31+
const lastNode = this.list.tail.previous.data;
32+
this.map.delete(lastNode.key);
33+
this.list.removeAtEnd();
34+
}
35+
} else {
36+
this.list.remove(this.map.get(key));
37+
this.list.addAtBeginning(data);
38+
this.map.set(key, this.list.head.next);
39+
}
40+
}
41+
42+
// this method will work in O(1)
43+
get(key) {
44+
if (this.map.has(key)) {
45+
const node = this.map.get(key);
46+
const { value } = node.data;
47+
this.list.remove(node);
48+
this.list.addAtBeginning({
49+
key,
50+
value,
51+
});
52+
this.map.set(key, this.list.head.next);
53+
}
54+
return false;
55+
}
56+
}
57+
58+
// const lru = new LRUCache(3);
59+
// lru.set(1, 1);
60+
// lru.set(2, 2);
61+
// lru.set(3, 3);
62+
// lru.set(4, 4);
63+
// lru.set(5, 5);
64+
// lru.set(2, 2);
65+
// lru.get(5, 5);
66+
// lru.list.display();
67+
68+
69+
module.exports = {
70+
LRUCache,
71+
};

src/_Classics_/fibonacci/index.js

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
//The Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21
12
// the algorithm has time complexity of O(n^2), very bad!
23
function fibonacci(position) {
34
// if position is 1 or 2, the number in fibonacci sequence will be 1
4-
if (position < 3) {
5-
return 1;
5+
if (position <= 1) {
6+
return position;
67
}
8+
79
// else the element in fibonacci sequence will be the sum of
810
// element at position(p) (p -1) and (p - 2)
911
return fibonacci(position - 2) + fibonacci(position - 1);
@@ -24,8 +26,8 @@ function fibonacciMemoized(index, cache) {
2426
if (cache[index]) {
2527
return cache[index];
2628
} else {
27-
if (index < 3) {
28-
return 1;
29+
if (index <=1) {
30+
return index;
2931
} else {
3032
cache[index] =
3133
fibonacciMemoized(index - 1, cache) +
@@ -41,7 +43,9 @@ function fibonacciMemoized(index, cache) {
4143

4244
function fibonacciTabular(n) {
4345
const table = [0, 1];
44-
46+
if (n <= 1) {
47+
return n;
48+
}
4549
for (let i = 2; i <= n; i += 1) {
4650
table[i] = table[i - 1] + table[i - 2];
4751
}
@@ -54,4 +58,4 @@ function fibonacciTabular(n) {
5458
// console.log(`Fib normal - ${fibonacci(number)}`);
5559
// console.log('--');
5660
// console.log(`Fib memo - ${fibonacciMemoized(number)}`);
57-
// console.log(`Fib table - ${fibonacciTabular(number)}`);
61+
// console.log(`Fib table - ${fibonacciTabular(number)}`);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* eslint-disable class-methods-use-this */
2+
class Node {
3+
constructor(data, previous, next) {
4+
this.data = data;
5+
this.previous = previous;
6+
this.next = next;
7+
}
8+
}
9+
10+
class DoublyLinkedList {
11+
constructor() {
12+
// head -> tail
13+
// head <- tail
14+
this.head = new Node(null, null, null);
15+
this.tail = new Node(null, null, null);
16+
this.head.next = this.tail; // head next point to tail
17+
this.tail.previous = this.head; // tail previous point to head
18+
this.size = 0;
19+
}
20+
21+
addAtBeginning(value) {
22+
const newNode = new Node(value, this.head, this.head.next);
23+
this.head.next.previous = newNode;
24+
this.head.next = newNode;
25+
this.size += 1;
26+
}
27+
28+
addAtEnd(value) {
29+
const newNode = new Node(value, this.tail.previous, this.tail);
30+
this.tail.previous.next = newNode;
31+
this.tail.previous = newNode;
32+
this.size += 1;
33+
}
34+
35+
removeAtBeginning() {
36+
this.remove(this.head.next);
37+
this.size -= 1;
38+
}
39+
40+
removeAtEnd() {
41+
this.remove(this.tail.previous);
42+
this.size -= 1;
43+
}
44+
45+
remove(node) {
46+
const previousNode = node.previous;
47+
const nextNode = node.next;
48+
previousNode.next = nextNode;
49+
nextNode.previous = previousNode;
50+
}
51+
52+
length() {
53+
return this.size;
54+
}
55+
56+
display() {
57+
let address = this.head.next;
58+
while (address !== this.tail) {
59+
console.log(address.data);
60+
address = address.next;
61+
}
62+
}
63+
}
64+
65+
module.exports = DoublyLinkedList;

src/_DataStructures_/LinkedList/loop-in-list/index.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Floyd’s Cycle-Finding Algorithm
22

3-
function detechLoop(linkedList) {
3+
function detectLoop(linkedList) {
44
let slow = linkedList.getFirst();
55
let fast = linkedList.getFirst();
66

@@ -14,3 +14,7 @@ function detechLoop(linkedList) {
1414
}
1515
return false;
1616
}
17+
18+
module.exports = {
19+
detectLoop,
20+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
const { LinkedList } = require('../index');
2+
const { detectLoop } = require('.');
3+
4+
describe('Loop a LinkedList', () => {
5+
let loopList = null;
6+
let last = null;
7+
beforeEach(() => {
8+
loopList = new LinkedList();
9+
loopList.addAtBeginning('1');
10+
loopList.addAtEnd('2');
11+
loopList.addAtEnd('3');
12+
loopList.addAtEnd('4');
13+
loopList.addAtEnd('5');
14+
// Create loop in list
15+
last = loopList.getLast();
16+
last.next = loopList.getFirst();
17+
});
18+
19+
it('Should break for empty list', () => {
20+
loopList.delete();
21+
expect(() => detectLoop(loopList)).toThrow(TypeError);
22+
});
23+
24+
it('Should return `true` when looping list', () => {
25+
expect(detectLoop(loopList)).toEqual(true);
26+
});
27+
28+
it('Should return `false` for non loop list', () => {
29+
last.next = null; // remove loop in list
30+
expect(detectLoop(loopList)).toEqual(false);
31+
});
32+
33+
it('Should return `false` for non loop list', () => {
34+
const list = new LinkedList();
35+
list.addAtBeginning('1');
36+
list.addAtEnd('1');
37+
list.addAtEnd('1');
38+
expect(detectLoop(list)).toEqual(false);
39+
});
40+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Evaluation of Postfix Expression
3+
* Input:456*+
4+
* Output:34
5+
*/
6+
7+
const Stack = require('../index');
8+
9+
function evaluatePostfixExpression(expression) {
10+
let s = new Stack();
11+
for (let i = 0; i < expression.length; i++) {
12+
const char = expression[i];
13+
if (!isNaN(char)) {
14+
//if number push the char onto stack
15+
s.push(Number(char));
16+
} else {
17+
// if char is an operator then pop two elements from stack, evaluate them accordingly based on operator.
18+
//push the result to stack
19+
let val1 = s.pop();
20+
let val2 = s.pop()
21+
switch (char) {
22+
case '+':
23+
s.push(val2 + val1);
24+
break;
25+
case '-':
26+
s.push(val2 - val1);
27+
break;
28+
case '*':
29+
s.push(val2 * val1);
30+
break;
31+
case '/':
32+
s.push(val2 / val1);
33+
break;
34+
35+
}
36+
}
37+
}
38+
//pop the value of postfix expression
39+
return s.pop();
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Given an integer N, remove consecutive repeated digits from it.
3+
* Input:133445
4+
* Output:1345
5+
*/
6+
7+
const Stack = require('../index');
8+
9+
10+
function removeConsecutiveDigits(no) {
11+
let s = new Stack();
12+
let newNo = "";
13+
//initally push first digit into stack
14+
newNo += no[0];
15+
s.push(no[0]);
16+
for (let i = 1; i < no.length; i++) {
17+
const digit = no[i];
18+
//if stack top and incoming digit is same ignore it else append to newNo.
19+
if (s.peek() !== digit) {
20+
newNo += digit;
21+
s.push(digit);
22+
}
23+
}
24+
return newNo
25+
}

0 commit comments

Comments
 (0)