LRU缓存
题目: 146. LRU 缓存
最近最少使用(Least Recently Used), 忘差不多了, 复习一下. 顺带一提 python 的 functools 提供 lru_cache 方法, 作为修饰器使用很方便.
维护一个链表, 遍历找 key 是否存在. 存在的话移到头部, 更新/获取 value; 不存在的话插在头上, 然后如果满了删掉尾巴即可.
题目要求 Get/Put 方法平均时间复杂度在O(1)上, 需要一个哈希表根据 key 直接找到节点. 需要双向链表简化插入/删除操作. 额外再记录下元素数量判断是否已满.
写出来时间只超过 18%, 看了下其他人的答案, 发现被废弃的节点可以复用, 省去额外的创建时间, 超过 82%.
type Node struct {
Key int
Val int
Prev *Node
Next *Node
}
type LRUCache struct {
Size int
Cap int
Elements *Node
Mapping map[int]*Node
}
func Constructor(capacity int) LRUCache {
root := &Node{}
root.Prev = root
root.Next = root
return LRUCache{
Size: 0,
Cap: capacity,
Elements: root,
Mapping: make(map[int]*Node),
}
}
func (this *LRUCache) Get(key int) int {
if node, exist := this.Mapping[key]; exist {
// move to head
node.Prev.Next = node.Next
node.Next.Prev = node.Prev
head := this.Elements
head.Next.Prev = node
node.Next = head.Next
head.Next = node
node.Prev = head
return node.Val
}
return -1
}
func (this *LRUCache) Put(key int, value int) {
head := this.Elements
if node, exist := this.Mapping[key]; exist {
// move to head
node.Prev.Next = node.Next
node.Next.Prev = node.Prev
head.Next.Prev = node
node.Next = head.Next
head.Next = node
node.Prev = head
node.Val = value
return
}
var node *Node
if this.Size >= this.Cap {
// remove tail
t := head.Prev
t.Prev.Next = t.Next
t.Next.Prev = t.Prev
delete(this.Mapping, t.Key)
node = t
} else {
this.Size++
node = &Node{}
}
node.Key = key
node.Val = value
head.Next.Prev = node
node.Next = head.Next
node.Prev = head
head.Next = node
this.Mapping[key] = node
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!