Skip to content

Commit 65538e2

Browse files
authored
Merge pull request knaxus#32 from knaxus/DoublyLinkList
doubly link list
2 parents 25c7a15 + 1789caf commit 65538e2

File tree

3 files changed

+142
-1
lines changed

3 files changed

+142
-1
lines changed

README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ Collection of interview questions with Unit Tests. Problems includes Data Struct
3434
- [Queue](src/_DataStructures_/Queue)
3535
- [Weave](src/_DataStructures_/Queue/weave)
3636

37+
- [Doubly Linked List](src/_DataStructures_/DoublyLinkedList)
3738
- [Suffix Tree](src/_DataStructures_/SuffixTree)
3839

39-
4040
### Logical Problems
4141

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

6464
- [Binary Search](src/_Searching_/BinarySearch)
6565

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

6873
- [A\*](src/PathFinder/AStart)

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

0 commit comments

Comments
 (0)