最近最少使用算法
双向链表+哈希表,值是双向链表节点
from typing import Optional
class Node:
# 提高访问属性的速度,并节省内存
__slots__ = 'prev', 'next', 'key', 'value'
def __init__(self, key=0, value=0):
self.key = key
self.value = value
class LRUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.dummy = Node() # 哨兵节点
self.dummy.prev = self.dummy
self.dummy.next = self.dummy
self.key_to_node = {}
# 获取 key 对应的节点,同时把该节点移到链表头部
def get_node(self, key: int) -> Optional[Node]:
if key not in self.key_to_node: # 没有这本书
return None
node = self.key_to_node[key] # 有这本书
self.remove(node) # 把这本书抽出来
self.push_front(node) # 放在最上面
return node
def get(self, key: int) -> int:
node = self.get_node(key) # get_node 会把对应节点移到链表头部
return node.value if node else -1
def put(self, key: int, value: int) -> None:
node = self.get_node(key) # get_node 会把对应节点移到链表头部
if node: # 有这本书
node.value = value # 更新 value
return
self.key_to_node[key] = node = Node(key, value) # 新书
self.push_front(node) # 放在最上面
if len(self.key_to_node) > self.capacity: # 书太多了
back_node = self.dummy.prev
del self.key_to_node[back_node.key]
self.remove(back_node) # 去掉最后一本书
# 删除一个节点(抽出一本书)
def remove(self, x: Node) -> None:
x.prev.next = x.next
x.next.prev = x.prev
# 在链表头添加一个节点(把一本书放在最上面)
def push_front(self, x: Node) -> None:
x.prev = self.dummy
x.next = self.dummy.next
x.prev.next = x
x.next.prev = xpackage main
import (
"container/list"
)
type entry struct {
key, value int
}
type LRUCache struct {
capacity int
list *list.List // 双向链表
keyToNode map[int]*list.Element
}
func Constructor(capacity int) LRUCache {
return LRUCache{capacity, list.New(), map[int]*list.Element{}}
}
func (c *LRUCache) Get(key int) int {
node := c.keyToNode[key]
if node == nil { // 没有这本书
return -1
}
c.list.MoveToFront(node) // 把这本书放在最上面
return node.Value.(entry).value
}
func (c *LRUCache) Put(key, value int) {
if node := c.keyToNode[key]; node != nil { // 有这本书
node.Value = entry{key, value} // 更新
c.list.MoveToFront(node) // 把这本书放在最上面
return
}
c.keyToNode[key] = c.list.PushFront(entry{key, value}) // 新书,放在最上面
if len(c.keyToNode) > c.capacity { // 书太多了
delete(c.keyToNode, c.list.Remove(c.list.Back()).(entry).key) // 去掉最后一本书
}
}