-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsolution.py
80 lines (64 loc) · 2.48 KB
/
solution.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
from collections import defaultdict
class ListNode:
def __init__(self, key: int = 0, value: int = 0):
self.key = key
self.value = value
self.freq = 1
self.prev = None
self.next = None
class DoubleyLinkedList:
def __init__(self):
self.size = 0
self.dummy_head = ListNode()
self.dummy_tail = ListNode()
self.dummy_head.next = self.dummy_tail # type: ignore
self.dummy_tail.prev = self.dummy_head # type: ignore
def __len__(self):
return self.size
def remove(self, node: ListNode) -> None:
self.size -= 1
previous_node, next_node = node.prev, node.next
next_node.prev = previous_node # type: ignore
previous_node.next = next_node # type: ignore
def remove_head(self) -> ListNode:
head = self.dummy_head.next
self.remove(head) # type: ignore
return head # type: ignore
def insert(self, node: ListNode) -> None:
self.size += 1
previous_node = self.dummy_tail.prev
self.dummy_tail.prev = previous_node.next = node # type: ignore
node.prev, node.next = previous_node, self.dummy_tail # type: ignore
class LFUCache:
def __init__(self, capacity: int):
self.cache = dict()
self.freq_table = defaultdict(DoubleyLinkedList)
self.capacity = capacity
self.min_freq = 0
def get(self, key: int) -> int:
if key not in self.cache:
return -1
return self.update_cache(self.cache[key], key, self.cache[key].value)
def put(self, key: int, value: int) -> None:
if not self.capacity:
return
if key in self.cache:
self.update_cache(self.cache[key], key, value)
else:
if len(self.cache) == self.capacity:
prev_head = self.freq_table[self.min_freq].remove_head()
del self.cache[prev_head.key]
new_node = ListNode(key, value)
self.freq_table[1].insert(new_node)
self.cache[key] = new_node
self.min_freq = 1
def update_cache(self, node: ListNode, key: int, new_value: int) -> int:
node = self.cache[key]
node.value = new_value
prev_freq = node.freq
node.freq += 1
self.freq_table[prev_freq].remove(node)
self.freq_table[node.freq].insert(node)
if prev_freq == self.min_freq and len(self.freq_table[prev_freq]) == 0:
self.min_freq += 1
return node.value