Leetcode-数据结构
q146 LRU缓存
题目传送门
题解
该题需要使用hash表+双向链表来解决。 我们把最常使用的节点放在链表头,而把最不常使用的节点放在链表尾,这样每次缓存容量满的时候就去掉表尾,每次访问或者添加节点的时候就将这个节点放在表头。 另外为了方便操作,我们为双向链表的两端加入了head和tail哨兵节点。 缓存中还有一个hash表,我们把key作为hash表的key,而把链表的整个节点作为hash表的value。
package main
type DLinkNode struct {
key, value int
prev, next *DLinkNode
}
type LRUCache struct {
size int
cap int
cache map[int] *DLinkNode
head, tail *DLinkNode
}
func InitDLinkNode(key, value int) *DLinkNode {
return &DLinkNode{
key: key,
value: value,
}
}
func Constructor(capacity int) LRUCache {
l := LRUCache{
size: 0,
cap: capacity,
cache: make(map[int]*DLinkNode),
head: InitDLinkNode(0, 0),
tail: InitDLinkNode(0, 0),
}
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 {
return -1
} else {
node := this.cache[key]
this.moveToHead(node)
return node.value
}
}
func (this *LRUCache) Put(key int, value int) {
if _, ok := this.cache[key]; !ok {
node := InitDLinkNode(key, value)
this.cache[key] = node
this.addToHead(node)
this.size++
if this.size > this.cap {
removed := this.removeTail()
delete(this.cache, removed.key)
this.size--
}
} else {
node := this.cache[key]
node.value = value
this.moveToHead(node)
}
}
func (this *LRUCache) addToHead(node *DLinkNode) {
node.prev = this.head
node.next = this.head.next
this.head.next.prev = node
this.head.next = node
}
func (this *LRUCache) removeNode(node *DLinkNode) {
node.prev.next = node.next
node.next.prev = node.prev
}
func (this *LRUCache) moveToHead(node *DLinkNode) {
this.removeNode(node)
this.addToHead(node)
}
func (this *LRUCache) removeTail() *DLinkNode {
node := this.tail.prev
this.removeNode(node)
return node
}
|