LRU
LRU题目,超级经典问题,重新复习一下,使用方法使用哈希表 + 双向链表;
涉及到很多指针的问题需要小心,其次还有封装函数成小功能,特别值得反复多练习;
type LRUCache struct {
size int
cap int
cache map[int] *Node
head, tail *Node
}
type Node struct{
key,val int
prev,next *Node
}
func initNode(k, v int) *Node{
return &Node{
key:k,
val:v,
}
}
func Constructor(capacity int) LRUCache {
l := LRUCache{
cache: map[int]*Node{},
cap: capacity,
head: initNode(0,0),
tail: initNode(0,0),
}
l.head.next = l.tail
l.tail.prev = l.head
return l
}
func (this *LRUCache) Get(key int) int {
/*将key对应的元素放到栈顶,其他元素出站*/
if _, ok := this.cache[key];!ok{
return -1
}
/*更新链表,把key放到最顶上*/
curNode := this.cache[key]
this.removeCurNode(curNode)
this.addHead(curNode)
return curNode.val
}
func (this *LRUCache) Put(key int, value int) {
if _, ok := this.cache[key]; !ok{
// 缓存中没有,
node := initNode(key, value)
this.cache[key] = node
// 把节点插入链表头
this.addHead(node)
this.size ++
if this.size > this.cap{
// 删除尾元素
removeEle := this.removeTail()
delete(this.cache, removeEle.key)
this.size --
}
}else{
// 缓存中存在,更新双向链表
node := this.cache[key]
node.val = value // 更新值
this.removeCurNode(node)
this.addHead(node)
}
}
func (this *LRUCache) removeTail() *Node{
p := this.tail.prev
this.removeCurNode(p)
return p
}
func (this *LRUCache) removeCurNode(curNode *Node){
curNode.prev.next = curNode.next
curNode.next.prev = curNode.prev
}
func (this *LRUCache)addHead(curNode *Node){
curNode.prev = this.head
curNode.next = this.head.next
this.head.next.prev = curNode
this.head.next = curNode
}