Skip to content

Commit 83f5f6f

Browse files
authored
Create 0460-lfu-cache.kt
1 parent 8703bee commit 83f5f6f

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

Diff for: kotlin/0460-lfu-cache.kt

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
class LFUCache(val capacity: Int) {
2+
var lfuCnt = 0
3+
val valueMap = HashMap<Int, Int>()
4+
val countMap = HashMap<Int, Int>()
5+
val listMap = HashMap<Int, LinkedList>()
6+
7+
fun counter(key: Int) {
8+
val cnt = countMap.getOrPut(key) { 0 }
9+
countMap[key] = countMap.getOrDefault(key, 0) + 1
10+
listMap.getOrPut(cnt) { LinkedList() }.apply { pop(key) }
11+
listMap.getOrPut(cnt + 1) { LinkedList() }.apply { pushRight(key) }
12+
13+
if (cnt == lfuCnt && (listMap[cnt]?.length() ?: 0) == 0)
14+
lfuCnt++
15+
}
16+
17+
fun get(key: Int): Int {
18+
valueMap[key]?.let { counter(key) }
19+
return valueMap[key] ?: -1
20+
}
21+
22+
fun put(key: Int, value: Int) {
23+
if (capacity == 0) return
24+
25+
if (key !in valueMap && valueMap.size == capacity) {
26+
listMap[lfuCnt]?.let {
27+
val toDel = it.popLeft()
28+
valueMap.remove(toDel)
29+
countMap.remove(toDel)
30+
}
31+
}
32+
33+
valueMap[key] = value
34+
counter(key)
35+
lfuCnt = minOf(lfuCnt, (countMap[key] ?: lfuCnt))
36+
}
37+
38+
}
39+
40+
class LinkedList {
41+
42+
val left = ListNode(0)
43+
var right = ListNode(0)
44+
val map = HashMap<Int, ListNode?>()
45+
46+
init {
47+
right.prev = left
48+
left.next = right
49+
}
50+
51+
fun length() = map.size
52+
53+
fun pushRight(value: Int) {
54+
val node = ListNode(value, right.prev, right)
55+
map[value] = node
56+
right.prev = node
57+
node.prev?.next = node
58+
}
59+
60+
fun pop(value: Int) {
61+
if (value in map) {
62+
val node = map[value]
63+
val next = node?.next
64+
val prev = node?.prev
65+
next?.prev = prev
66+
prev?.next = next
67+
map.remove(value)
68+
}
69+
}
70+
71+
fun popLeft(): Int {
72+
val res = left.next?.value
73+
res?.let { pop(it) }
74+
return res ?: -1
75+
}
76+
77+
fun update(value: Int) {
78+
pop(value)
79+
pushRight(value)
80+
}
81+
82+
class ListNode(
83+
var value: Int,
84+
var prev: ListNode? = null,
85+
var next: ListNode? = null
86+
)
87+
}

0 commit comments

Comments
 (0)