LRU缓冲机制
使用有序字典
class LRUCache(collections.OrderedDict): # collections.OrderedDict
def __init__(self, capacity: int):
super().__init__() # 初始化父类(超类)
self.capacity = capacity
def get(self, key: int) -> int:
if key not in self:
return -1
self.move_to_end(key)
return self[key]
def put(self, key: int, value: int) -> None:
if key in self:
self.move_to_end(key)
self[key] = value
if len(self) > self.capacity:
self.popitem(last = False)
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
使用字典加双向链表
class DLinkedNode:
def __init__(self, key, value):
self.key = key
self.value = value
self.prev = None
self.next = None
class LRUCache:
def __init__(self, capacity: int):
self.phead = DLinkedNode(0, 0)
self.ptail = DLinkedNode(0, 0)
self.phead.next = self.ptail
self.ptail.prev = self.phead
self.capacity = capacity
self.cache = {}
self.size = 0
def get(self, key: int) -> int:
if key not in self.cache.keys():
return -1
node = self.cache[key]
self.moveToHead(node)
return node.value
def put(self, key: int, value: int) -> None:
if key in self.cache.keys():
node = self.cache[key]
node.value = value
self.moveToHead(node)
else:
self.size += 1
newNode = DLinkedNode(key, value)
self.cache[key] = newNode
self.addToHead(newNode)
if self.size > self.capacity:
removed = self.removeTail()
self.cache.pop(removed.key)
self.size -= 1
def removeNode(self, node):
node.prev.next = node.next
node.next.prev = node.prev
def addToHead(self, node):
tmp = self.phead.next
self.phead.next = node
node.prev = self.phead
node.next = tmp
tmp.prev = node
"""
node.prev = self.phead
node.next = self.phead.next
self.phead.next.prev = node
self.phead.next = node
"""
def moveToHead(self, node):
self.removeNode(node)
self.addToHead(node)
def removeTail(self):
node = self.ptail.prev
self.removeNode(node)
return node
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
牛客网题目 LRU缓存机制
使用有序字典:
#
# lru design
# @param operators int整型二维数组 the ops
# @param k int整型 the k
# @return int整型一维数组
#
#
# lru design
# @param operators int整型二维数组 the ops
# @param k int整型 the k
# @return int整型一维数组
#
import collections
class Solution:
def __init__(self, k):
self.dic = collections.OrderedDict()
self.capacity = k # k表示剩余容量
def get(self, key):
if key not in self.dic: return -1
val = self.dic.pop(key) # 返回键值, 但是也没必要这一项弹出来啊,可以改该
print("val", val)
self.dic[key] = val
return val
def set(self, key, value): # 这里是弹出来,然后又加进入,相当于把这一项移动到末尾。
if key in self.dic:
self.dic.pop(key)
else:
if self.capacity > 0:
self.capacity -= 1
else:
self.dic.popitem(last=False) # 把最前面的弹出来,最末尾的表示最近访问过的。
self.dic[key] = value
s = input().strip()
print("s", s)
idx = s.index("]],")
k = int(s[idx+3:])
ss = s[:idx]
aa = ss.strip("[[").split("],[")
s = Solution(k)
res = []
for r in aa:
ss = list(map(int, r.strip().split(",")))
if ss[0] == 1:
s.set(ss[1], ss[2])
elif ss[0] == 2:
x = s.get(ss[1])
res.append(x)
print(str(res).replace(" ", ""))
普通字典 + 链表
#
# lru design
# @param operators int整型二维数组 the ops
# @param k int整型 the k
# @return int整型一维数组
#
class node:
def __init__(self, key, value):
self.key = key
self.value = value
self.pre = None
self.next = None
class Solution:
def LRU(self, operators, k):
# write code here
self.cache = {}
self.nums = 0
self.result = []
self.pHead = node(0, 0)
self.pTail = node(0, 0)
self.pHead.next = self.pTail
self.pTail.pre = self.pHead
for item in operators:
ops, *res = item
# print("ops, res", ops, res)
if ops == 1:
key, value = res
# print("key, value", key, value)
if key not in self.cache.keys():
self.cache[key] = node(key, value)
# print("not in keys()", key)
self.addToHead(key)
self.nums += 1
else:
self.cache[key].value = value
# print("self.cache",self.cache)
# print("key1", key)
self.moveToHead(key)
if self.nums > k:
delkey = self.pTail.pre.key
# print("delkey", delkey)
self.removeNode(delkey)
self.cache.pop(delkey) # 根据最后一个节点来定位
self.nums -= 1
else:
key = res[0]
# print("else key", key)
if key in self.cache.keys():
self.result.append(self.cache[key].value)
self.moveToHead(key)
else:
self.result.append(-1)
return self.result
def addToHead(self, key):
node1 = self.cache[key]
node1.pre = self.pHead
node1.next = self.pHead.next
self.pHead.next = node1
node1.next.pre = node1
def removeNode(self, key):
node2 = self.cache[key]
node2.pre.next = node2.next
node2.next.pre = node2.pre
def moveToHead(self, key):
self.removeNode(key)
self.addToHead(key)
普通字典 + 链表 更清晰的方式
注意删除链表节点和删除字典的节点, 这个时候的处理,先将待删除节点单独拿出来,再处理。
#
# lru design
# @param operators int整型二维数组 the ops
# @param k int整型 the k
# @return int整型一维数组
#
class node:
def __init__(self, key, value):
self.key = key
self.value = value
self.pre = None
self.next = None
class Solution:
def LRU(self, operators, k):
# write code here
self.cache = {}
self.capacity = 0
self.k = k
self.res = []
self.pHead = node(0, 0)
self.pTail = node(0, 0)
self.pHead.next = self.pTail
self.pTail.pre = self.pHead
for item in operators:
flag, *reslist = item # reslist 是一个列表
if flag == 1:
key, value = reslist
self.set(key, value)
else:
key = reslist[0]
a = self.get(key)
self.res.append(a)
return self.res
def set(self, key, value):
if key in self.cache.keys():
node1 = self.cache[key]
node1.value = value
self.moveToHead(node1)
else:
newnode = node(key, value)
self.cache[key] = newnode # 将节点加入缓存
self.addToHead(newnode)
self.capacity += 1
if self.capacity > self.k:
removednode = self.pTail.pre # 待删除的节点
self.removeNode(removednode) # 从链表中断开
self.cache.pop(removednode.key) # 从缓存中弹出
self.capacity -= 1
def get(self, key):
if key not in self.cache.keys():
return -1
node2 = self.cache[key]
self.moveToHead(node2)
return node2.value
def removeNode(self, node):
node.pre.next = node.next
node.next.pre = node.pre
def addToHead(self, node):
node.pre = self.pHead
node.next = self.pHead.next
self.pHead.next = node
node.next.pre = node
def moveToHead(self, node):
self.removeNode(node)
self.addToHead(node)
# str = input()
# liststr = str[:-2]
# # string = "list1 = " + liststr
# string2 = "list1 = list(" + liststr + ")"
# exec(string2)
# nums = int(str[-1])
# print(list1, nums)
# print(len(list1))
list1 = [[1,1,1],[1,2,2],[1,3,2],[2,1],[1,4,4],[2,2]]
sol = Solution()
k = 3
res1 = sol.LRU(list1,k)
print("res1",res1)
更新(2020-10-5):普通字典+链表
#
# lru design
# @param operators int整型二维数组 the ops
# @param k int整型 the k
# @return int整型一维数组
#
class Node:
def __init__(self, key, value):
self.key = key
self.value = value
self.next = None
self.pre = None
class Solution:
def __init__(self):
self.cache = {}
self.capacity = 0
self.head = Node(0, 0)
self.tail = Node(0, 0)
self.head.next = self.tail
self.tail.pre = self.head
self.result = []
def LRU(self, operators, k):
# write code here
self.capacity = k
for item in operators:
flag, *res_list = item
if flag == 1:
key, value = res_list
self.set(key, value)
else:
key = res_list[0]
value_return = self.get(key) # 返回节点的值
self.result.append(value_return)
return self.result
def set(self, key, value):
if key in self.cache.keys():
cur_node = self.cache[key]
cur_node[key] = value
self.move_to_head(cur_node)
else:
new_node = Node(key, value)
self.add_to_head(new_node)
self.cache[key] = new_node # 之前忘了加进去
self.capacity -= 1
if self.capacity < 0: # 不能写成 <= 0 , 当 == 0 时,表明还没有溢出, 只有绝对小于0时才能进行删除操作
node_to_delet = self.tail.pre
self.remove_node(node_to_delet)
self.capacity += 1
self.cache.pop(node_to_delet.key)
def get(self, key): # 返回节点的值 或者 -1
if key not in self.cache.keys():
return -1
cur_node = self.cache[key]
self.move_to_head(cur_node)
return cur_node.value
def remove_node(self, node):
node.pre.next = node.next
node.next.pre = node.pre
def add_to_head(self, node):
node.pre = self.head
node.next = self.head.next
self.head.next = node
node.next.pre = node
def move_to_head(self, node):
self.remove_node(node)
self.add_to_head(node)