Skip to content

Commit a63678c

Browse files
committed
Create 0460-lfu-cache.js
1 parent 48eed3a commit a63678c

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

javascript/0460-lfu-cache.js

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// https://leetcode.com/problems/lfu-cache/
2+
3+
class ListNode {
4+
constructor(val, next, prev) {
5+
this.val = (val===undefined ? 0 : val)
6+
this.next = (next===undefined ? null : next)
7+
this.prev = (next===undefined ? null : prev)
8+
}
9+
}
10+
11+
class LinkedList {
12+
constructor() {
13+
this.map = new Map()
14+
this.Right = new ListNode(null)
15+
this.Left = new ListNode(null, this.Right)
16+
this.Right.prev = this.Left
17+
}
18+
19+
len() {
20+
return this.map.size
21+
}
22+
23+
pop(val) {
24+
if (this.map.has(val)) {
25+
let node = this.map.get(val)
26+
27+
// save
28+
let prevNode = node.prev
29+
// delete
30+
prevNode.next = node.next
31+
prevNode.next.prev = prevNode
32+
this.map.delete(val)
33+
}
34+
}
35+
36+
popleft() {
37+
let data = this.Left.next.val
38+
this.Left.next = this.Left.next.next
39+
this.Left.next.prev = this.Left
40+
this.map.delete(data)
41+
return data
42+
}
43+
44+
pushRight(val) {
45+
let newNode = new ListNode(val, this.Right)
46+
newNode.prev = this.Right.prev
47+
newNode.prev.next = newNode
48+
this.Right.prev = newNode
49+
this.map.set(val, newNode)
50+
}
51+
52+
update(val) {
53+
this.pop(val)
54+
this.pushRight(val)
55+
}
56+
}
57+
58+
/**
59+
* @param {number} capacity
60+
*/
61+
var LFUCache = function(capacity) {
62+
this.capacity = capacity
63+
this.valueMap = new Map()
64+
this.countMap = new Map()
65+
this.lftCount = 1
66+
this.lists = []
67+
this.counter = (key) => {
68+
let count = this.countMap.get(key) || 0
69+
if (this.lists[count]) {
70+
this.lists[count].pop(key)
71+
}
72+
if (!this.lists[count + 1]) {
73+
this.lists[count + 1] = new LinkedList()
74+
}
75+
this.lists[count + 1].pushRight(key)
76+
this.countMap.set(key, count + 1)
77+
// console.log(this.lftCount == count, count, this.lists[count].len())
78+
if (this.lftCount == count && this.lists[count] && this.lists[count].len() === 0) {
79+
this.lftCount++
80+
}
81+
}
82+
};
83+
84+
/**
85+
* @param {number} key
86+
* @return {number}
87+
*/
88+
LFUCache.prototype.get = function(key) {
89+
if (!this.valueMap.has(key)) {
90+
return -1
91+
}
92+
93+
this.counter(key)
94+
return this.valueMap.get(key)
95+
};
96+
97+
/**
98+
* @param {number} key
99+
* @param {number} value
100+
* @return {void}
101+
*/
102+
LFUCache.prototype.put = function(key, value) {
103+
104+
if (!this.valueMap.has(key) && this.valueMap.size == this.capacity) {
105+
// we need to evict
106+
// console.log(this.lists[this.lftCount])
107+
let evictedKey = this.lists[this.lftCount].popleft()
108+
this.valueMap.delete(evictedKey)
109+
this.countMap.delete(evictedKey)
110+
}
111+
112+
this.valueMap.set(key, value)
113+
this.counter(key)
114+
this.lftCount = Math.min(this.countMap.get(key), this.lftCount)
115+
};
116+
/**
117+
* Your LFUCache object will be instantiated and called as such:
118+
* var obj = new LFUCache(capacity)
119+
* var param_1 = obj.get(key)
120+
* obj.put(key,value)
121+
*/

0 commit comments

Comments
 (0)