class Node:
def __init__(self, key, val):
self.next = None
self.prev = None
self.freq = 0
self.val = val
self.key = key
class Head:
def __init__(self):
self.head = None
self.tail = None
def push(self, node):
if self.head:
oldHead = self.head
oldHead.prev = node
self.head = node
self.head.next = oldHead
else:
self.head = node
self.tail = node
pass
def pop(self):
if self.head == self.tail:
node = self.head
self.head = None
self.tail = None
else:
node = self.head
nextHead = self.head.next
nextHead.prev = None
self.head = nextHead
node.next = None
node.prev = None
return node
def swap(self, node1, node2):
prevNode = node1.prev
nextNode = node2.next
if node1 is self.head:
self.head = node2
if node2 == self.tail:
self.tail = node1
if prevNode:
prevNode.next = node2
if nextNode:
nextNode.prev = node1
node1.next = nextNode
node1.prev = node2
node2.next = node1
node2.prev = prevNode
class LFUCache:
def __init__(self, capacity):
self.head = Head()
self.dict = {}
self.capacity = capacity
pass
def put(self, key, val):
if key in self.dict:
node = self.dict[key]
node.val = val
node.freq += 1
while node.next and node.freq >= node.next.freq:
self.head.swap(node, node.next)
else:
node = Node(key, val)
if len(self.dict) == self.capacity:
oldNode = self.head.pop()
if oldNode:
self.dict.pop(oldNode.key, None)
if len(self.dict) < self.capacity:
self.dict[key] = node
self.head.push(node)
while node.next and node.freq >= node.next.freq:
self.head.swap(node, node.next)
def get(self, key):
if key in self.dict:
node = self.dict[key]
node.freq += 1
while node.next and node.freq >= node.next.freq:
self.head.swap(node, node.next)
return node.val
else:
return -1
def assertEquals(exp, act):
if exp != act:
print(exp, act)