方法一:
class LFUCache:
def __init__(self, capacity: int):
self.c, self.__count = capacity, 0
self.keys = {} # {key:int, value = [value, fre, time]}
def get(self, key: int) -> int:
self.__count += 1
if key in self.keys:
self.keys[key][1] += 1
self.keys[key][2] = self.__count
return self.keys[key][0]
else:
return -1
def put(self, key: int, value: int) -> None:
self.__count += 1
if self.c == 0:
return
if key not in self.keys:
if len(self.keys) >= self.c:
min_keys = []
min_fre = self.keys[min(self.keys, key = lambda x:self.keys[x][1])][1]
for k in self.keys:
if self.keys[k][1] == min_fre:
min_keys.append(k)
min_time, least_key = 1e8, 0
for k in min_keys:
if self.keys[k][2] < min_time:
min_time = self.keys[k][2]
least_key = k
del self.keys[least_key]
self.keys[key] = [value, 1, self.__count]
else:
self.keys[key][0] = value
self.keys[key][1] += 1
self.keys[key][2] = self.__count
# Your LFUCache object will be instantiated and called as such:
# obj = LFUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
方法二:
class Node:
def __init__(self, key, val, pre=None, nex=None, freq=0):
self.pre = pre
self.nex = nex
self.freq = freq
self.val = val
self.key = key
def insert(self, nex):
nex.pre = self
nex.nex = self.nex
self.nex.pre = nex
self.nex = nex
def create_linked_list():
head = Node(0, 0)
tail = Node(0, 0)
head.nex = tail
tail.pre = head
return (head, tail)
class LFUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.size = 0
self.minFreq = 0
self.freqMap = collections.defaultdict(create_linked_list)
self.keyMap = {}
def delete(self, node):
if node.pre:
node.pre.nex = node.nex
node.nex.pre = node.pre
if node.pre is self.freqMap[node.freq][0] and node.nex is self.freqMap[node.freq][-1]:
self.freqMap.pop(node.freq)
return node.key
def increase(self, node):
node.freq += 1
self.delete(node)
self.freqMap[node.freq][-1].pre.insert(node)
if node.freq == 1:
self.minFreq = 1
elif self.minFreq == node.freq - 1:
head, tail = self.freqMap[node.freq - 1]
if head.nex is tail:
self.minFreq = node.freq
def get(self, key: int) -> int:
if key in self.keyMap:
self.increase(self.keyMap[key])
return self.keyMap[key].val
return -1
def put(self, key: int, value: int) -> None:
if self.capacity != 0:
if key in self.keyMap:
node = self.keyMap[key]
node.val = value
else:
node = Node(key, value)
self.keyMap[key] = node
self.size += 1
if self.size > self.capacity:
self.size -= 1
deleted = self.delete(self.freqMap[self.minFreq][0].nex)
self.keyMap.pop(deleted)
self.increase(node)