原题
https://leetcode.cn/problems/lru-cache/description/
思路
字典 + 双向链表
复杂度
时间:O(1)
空间:O(n)
Python代码
# 双向链表节点
class Node:
def __init__(self, key: int, value: int):
self.key = key
self.value = value
self.prev = None
self.next = None
class LRUCache:
def __init__(self, capacity: int):
# 字典存储key和node
self.cache = dict()
self.capacity = capacity
# 初始化头部和尾部虚拟节点
self.head = Node(0, 0)
self.tail = Node(0, 0)
self.head.next = self.tail
self.tail.prev = self.head
def get(self, key: int) -> int:
if key in self.cache:
# 删除节点
node = self.cache[key]
self.remove(node)
# 在尾部新增节点
self.add(node)
return node.value
else:
return -1
def put(self, key: int, value: int) -> None:
if key in self.cache:
# 删除节点
node = self.cache[key]
self.remove(node)
# 在尾部新增节点
self.add(Node(key, value))
if len(self.cache) > self.capacity:
# 逐出最久未使用的关键字
self.remove(self.head.next)
# 删除节点
def remove(self, node: Node) -> None:
del self.cache[node.key]
# 在双向链表里删除节点
node.prev.next = node.next
node.next.prev = node.prev
# 在尾部新增节点
def add(self, node: Node) -> None:
self.cache[node.key] = node
# 将节点加入双向链表的尾部
prev = self.tail.prev
prev.next = node
node.prev = prev
node.next = self.tail
self.tail.prev = node
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
Go代码
// 双向链表节点
type Node struct {
key, value int
prev, next *Node
}
type LRUCache struct {
// 字典存储key和节点指针
cache map[int]*Node
capacity int
head *Node
tail *Node
}
func Constructor(capacity int) LRUCache {
l := LRUCache{cache: map[int]*Node{}, capacity: capacity, head: &Node{}, tail: &Node{}}
// 初始化头部和尾部虚拟节点指针
l.head.next = l.tail
l.tail.prev = l.head
return l
}
func (this *LRUCache) Get(key int) int {
if _, ok := this.cache[key]; ok {
// 删除节点指针
node := this.cache[key]
this.Remove(node)
// 在尾部新增节点指针
this.Add(node)
return node.value
} else {
return -1
}
}
func (this *LRUCache) Put(key int, value int) {
if _, ok := this.cache[key]; ok {
node := this.cache[key]
this.Remove(node)
}
// 在尾部新增节点指针
this.Add(&Node{key: key, value: value})
if len(this.cache) > this.capacity {
// 逐出最久未使用的关键字
this.Remove(this.head.next)
}
}
// 删除节点指针
func (this *LRUCache) Remove(node *Node) {
delete(this.cache, node.key)
// 在双向链表里删除节点指针
node.prev.next = node.next
node.next.prev = node.prev
}
// 在尾部新增节点指针
func (this *LRUCache) Add(node *Node) {
this.cache[node.key] = node
// 将节点加入双向链表的尾部
prev := this.tail.prev
prev.next = node
node.prev = prev
node.next = this.tail
this.tail.prev = node
}
/**
* Your LRUCache object will be instantiated and called as such:
* obj := Constructor(capacity);
* param_1 := obj.Get(key);
* obj.Put(key,value);
*/
1187

被折叠的 条评论
为什么被折叠?



