题目:
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
LRUCache(int capacity)以 正整数 作为容量capacity初始化 LRU 缓存int get(int key)如果关键字key存在于缓存中,则返回关键字的值,否则返回-1。void put(int key, int value)如果关键字key已经存在,则变更其数据值value;如果不存在,则向缓存中插入该组key-value。如果插入操作导致关键字数量超过capacity,则应该 逐出 最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。
解法:
双向链表+hash表
type LRUCache struct {
Cache map[int]*LinkNode
Link *LinkNode
Head *LinkNode
Capacity int
}
type LinkNode struct {
Pre *LinkNode
Next *LinkNode
Val int
Key int
}
func Constructor(capacity int) LRUCache {
return LRUCache{
Cache: make(map[int]*LinkNode),
// LinkDummyHead: &LinkNode{},
Capacity: capacity,
}
}
func (this *LRUCache) Get(key int) int {
if node, ok := this.Cache[key]; ok {
this.MoveToHead(node)
// fmt.Println("get",key)
return node.Val
}
return -1
}
func (this *LRUCache) Put(key int, value int) {
if node, ok := this.Cache[key]; ok {
node.Val = value
this.MoveToHead(node)
// fmt.Println("put",key, value)
} else {
nd := &LinkNode{Key:key, Val:value}
if len(this.Cache) == 0 {
nd.Pre = nd
nd.Next = nd
this.Head = nd
} else if len(this.Cache) == this.Capacity {
this.AddToHead(nd)
nKey := this.RemoveTail()
delete(this.Cache, nKey)
} else {
this.AddToHead(nd)
}
this.Cache[key] = nd
}
}
func (this *LRUCache) AddToHead(node *LinkNode) {
head := this.Head
headPre := head.Pre
headPre.Next = node
node.Next = head
node.Pre = headPre
head.Pre = node
this.Head = node
}
func (this *LRUCache) RemoveTail() int {
head := this.Head
tail := head.Pre
tailPre := tail.Pre
tailPre.Next = head
head.Pre = tailPre
return tail.Key
}
// node移动到头节点
func (this *LRUCache) MoveToHead(node *LinkNode) {
// 这里如果不这样处理会有问题,head节点会被摘掉
if this.Head == node {
return
}
// 摘除node节点
nodePre := node.Pre
nodeNext := node.Next
nodePre.Next = nodeNext
nodeNext.Pre = nodePre
// node节点移动到head
tail := this.Head.Pre
head := this.Head
tail.Next = node
head.Pre = node
node.Pre = tail
node.Next = head
this.Head = node
// fmt.Printf("MoveToHead head:%+v, tail:%+v\n", *head, *tail)
}