-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy path146. LRU Cache.py
65 lines (54 loc) · 1.97 KB
/
146. LRU Cache.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
class LRUCache(object):
def __init__(self, capacity):
"""
:type capacity: int
"""
from collections import deque
from collections import Counter
self.capacity = capacity
self.cache = dict()
self.keyQueue = deque() # queue of keys used, left is old, right is new
self.keyCounter = Counter() # count how many keys are in keyQueue
def _shrinkKeyQueue(self):
"""
When keyQueue has lots of keys appearing multiple times, we need to go over it and make it concise
This is required, just to save space
"""
if len(self.keyQueue) > 2 * self.capacity:
self.keyCounter.clear()
from collections import deque
newKeyQueue = deque()
while len(self.keyCounter) < len(self.cache):
key = self.keyQueue.pop()
if key not in self.keyCounter:
self.keyCounter[key] += 1
newKeyQueue.appendleft(key)
self.keyQueue.clear()
self.keyQueue = newKeyQueue
def get(self, key):
"""
:rtype: int
"""
if key in self.cache:
self.keyQueue.append(key)
self.keyCounter[key] += 1
self._shrinkKeyQueue() # not absolutely necessary, just to save space
return self.cache[key]
else:
return -1
def set(self, key, value):
"""
:type key: int
:type value: int
:rtype: nothing
"""
self.cache[key] = value
self.keyQueue.append(key)
self.keyCounter[key] += 1
while len(self.cache) > self.capacity:
oldestKey = self.keyQueue.popleft()
self.keyCounter[oldestKey] -= 1
if self.keyCounter[oldestKey]==0:
del self.keyCounter[oldestKey]
del self.cache[oldestKey]
self._shrinkKeyQueue() # not absolutely necessary, just to save space