Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.
Finally, you need to return the data from each get.
Example 1:
Input:
LRUCache(2)
set(2, 1)
set(1, 1)
get(2)
set(4, 1)
get(1)
get(2)
Output: [1,-1,1]
Explanation:
cache cap is 2,set(2,1),set(1, 1),get(2) and return 1,set(4,1) and delete (1,1),because (1,1)is the least use,get(1) and return -1,get(2) and return 1.
Example 2:
Input:
LRUCache(1)
set(2, 1)
get(2)
set(3, 2)
get(2)
get(3)
Output:[1,-1,2]
Explanation:
cache cap is 1,set(2,1),get(2) and return 1,set(3,2) and delete (2,1),get(2) and return -1,get(3) and return 2.
class node:
def __init__(self, key=None, val=None):
self.key = key
self.val = val
self.next = None
class LRUCache:
"""
@param: capacity: An integer
"""
def __init__(self, capacity):
self.cap = capacity
self.previous_node = {}
self.dummy = node()
self.end = self.dummy
def list_append(self, new_node):
# make connection to its previous
self.previous_node[new_node.key] = self.end
# make connection to its next
self.end.next = new_node
# move the list end
self.end = new_node
# make a marker at the tail so that it is an end
self.end.next = None
def list_pop(self, old_node):
# if not a node
if old_node is None:
return
# make connection from left to right
self.previous_node[old_node.key].next = old_node.next
# make connection from right to left
if old_node.next is not None:
self.previous_node[old_node.next.key] = self.previous_node[old_node.key]
else: # if old node is tail
self.end = self.previous_node[old_node.key]
# remove old_node's key from dict()
del self.previous_node[old_node.key]
return old_node
def list_kick(self, key):
# find the node
the_node = self.previous_node[key].next
# if it is tail then no need to kick
if the_node.next is None:
return
# pop the_node and append it to right
self.list_append(self.list_pop(the_node))
"""
@param: key: An integer
@return: An integer
"""
def get(self, key):
# if key not in catch
if key not in self.previous_node:
return -1
# move the related node to the end
self.list_kick(key)
# the value of tail should be the answer
return self.end.val
"""
@param: key: An integer
@param: value: An integer
@return: nothing
"""
def set(self, key, value):
# if an exsited key
if key in self.previous_node:
# move to tail
self.list_kick(key)
# set the value again
self.end.val = value
return
# if a new key
# create a new node
new_node = node(key, value)
# append it to tail
self.list_append(new_node)
# if over sized
if len(self.previous_node) > self.cap:
# pop the first on after dummy
self.list_pop(self.dummy.next)
return
self.list_append(self.list_pop(the_node)),直接把输入值返回。