Skip to content

fix Fibonacci series problem #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Oct 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
6855dce
--update : add doubly link list
TheSTL Oct 5, 2019
84feda9
--refactor : refactor length function
TheSTL Oct 5, 2019
53ac17a
--fix : fix doublyLinkedList length
TheSTL Oct 5, 2019
7b9dd7e
--update : add LRUCache data structure
TheSTL Oct 5, 2019
261695e
--update : move LRU cache into _Algorithms_
TheSTL Oct 5, 2019
aae9142
--fix : fix require
TheSTL Oct 5, 2019
2db8441
--update : README.md
TheSTL Oct 5, 2019
5aeb51b
fix: More meaningful name
ashokdey Oct 7, 2019
97b727b
handling fibonacci for negative numbers and 0
SumeetHaryani Oct 7, 2019
f6d18ed
Merge pull request #33 from SumeetHaryani/master
ashokdey Oct 7, 2019
572e16a
--update : add SuffixTree
TheSTL Oct 7, 2019
2759173
Add unit test to loop-in-list
DaniloBarros Oct 8, 2019
f3a3956
Merge pull request #46 from DaniloBarros/add-test-to-loop-in-list
ashokdey Oct 8, 2019
25c7a15
Merge pull request #45 from knaxus/SuffixTree
ashokdey Oct 8, 2019
1789caf
Merge branch 'master' into DoublyLinkList
ashokdey Oct 8, 2019
65538e2
Merge pull request #32 from knaxus/DoublyLinkList
ashokdey Oct 8, 2019
05aa185
Update README.md
ashokdey Oct 8, 2019
421200c
Merge branch 'master' of github.com:knaxus/problem-solving-javascript…
ashokdey Oct 8, 2019
31c5648
refactor: folder structure
ashokdey Oct 8, 2019
f32e9aa
update: BST insertion added
ashokdey Oct 8, 2019
7b65d6a
update: preorder traversal
ashokdey Oct 8, 2019
22787dd
update: return pre-order traversal as an array
ashokdey Oct 8, 2019
312e43a
cleanup
ashokdey Oct 8, 2019
34593cb
cleanup
ashokdey Oct 8, 2019
78cb213
update: implementation of Inorder Traversal
ashokdey Oct 8, 2019
5fd958e
update: added Postorder traversal
ashokdey Oct 8, 2019
8fae46e
update: entry for trees in README
ashokdey Oct 8, 2019
3475013
update: search in BST
ashokdey Oct 8, 2019
1cd6613
Merge pull request #49 from knaxus/problems
ashokdey Oct 8, 2019
886e4fd
add test smallest number
Oct 8, 2019
0256f44
add new scenario
Oct 8, 2019
b52001e
Merge pull request #50 from dwncy/feature/test-smallest-number
ashokdey Oct 8, 2019
b3139d7
fix fibonacci problem for negative numbers
SumeetHaryani Oct 8, 2019
01415ff
fix merge conflict
SumeetHaryani Oct 8, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,22 @@ 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)
- [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)

- [Trees](src/_DataStructures_/Trees)
- [Binary Search Tree](src/_DataStructures_/Trees/BST)
- [Suffix Tree](src/_DataStructures_/SuffixTree)

### Logical Problems

- [Anagrams](src/_Problems_/anagrams)
Expand All @@ -60,6 +66,10 @@ 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)
Expand All @@ -69,8 +79,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.
Expand Down
71 changes: 71 additions & 0 deletions src/_Algorithms_/lru-cache/index.js
Original file line number Diff line number Diff line change
@@ -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('../../_DataStructures_/DoublyLinkedList/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,
};
13 changes: 10 additions & 3 deletions src/_Classics_/fibonacci/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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) +
Expand All @@ -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];
Expand Down
65 changes: 65 additions & 0 deletions src/_DataStructures_/DoublyLinkedList/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/* 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
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.size += 1;
}

addAtEnd(value) {
const newNode = new Node(value, this.tail.previous, this.tail);
this.tail.previous.next = newNode;
this.tail.previous = newNode;
this.size += 1;
}

removeAtBeginning() {
this.remove(this.head.next);
this.size -= 1;
}

removeAtEnd() {
this.remove(this.tail.previous);
this.size -= 1;
}

remove(node) {
const previousNode = node.previous;
const nextNode = node.next;
previousNode.next = nextNode;
nextNode.previous = previousNode;
}

length() {
return this.size;
}

display() {
let address = this.head.next;
while (address !== this.tail) {
console.log(address.data);
address = address.next;
}
}
}

module.exports = DoublyLinkedList;
6 changes: 5 additions & 1 deletion src/_DataStructures_/LinkedList/loop-in-list/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Floyd’s Cycle-Finding Algorithm

function detechLoop(linkedList) {
function detectLoop(linkedList) {
let slow = linkedList.getFirst();
let fast = linkedList.getFirst();

Expand All @@ -14,3 +14,7 @@ function detechLoop(linkedList) {
}
return false;
}

module.exports = {
detectLoop,
};
40 changes: 40 additions & 0 deletions src/_DataStructures_/LinkedList/loop-in-list/loop-in-list.test.js
Original file line number Diff line number Diff line change
@@ -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);
});
});
7 changes: 7 additions & 0 deletions src/_DataStructures_/Trees/BST/Node.js
Original file line number Diff line number Diff line change
@@ -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
}
};
110 changes: 110 additions & 0 deletions src/_DataStructures_/Trees/BST/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
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) {
// eslint-disable-next-line no-param-reassign
root.leftChild = this.insert(root.leftChild, value);
return root;
}
if (value > root.value) {
// eslint-disable-next-line no-param-reassign
root.rightChild = this.insert(root.rightChild, value);
return root;
}
return root;
}

preorder(root) {
/** returning an array so as to make testing easy */
let arr = [];
if (root === null) return [];
arr.push(root.value);

const left = this.preorder(root.leftChild);
arr = [...arr, ...left];

const right = this.preorder(root.rightChild);
arr = [...arr, ...right];
return arr;
}

inorder(root) {
/** left - root - right */
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;
}

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];
}

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);
// console.log(bst.root);
// bst.insert(bst.root, 4);
// bst.insert(bst.root, 9);
// 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 preorder = bst.preorder(bst.root);
// console.log('Preorder Traversal - ', preorder);

// const inorder = bst.inorder(bst.root);
// console.log('Inorder Traversal - ', inorder);

// 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;
Loading