91 lines
1.6 KiB
Go
91 lines
1.6 KiB
Go
package top100liked
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
)
|
|
|
|
// https://leetcode.cn/problems/lru-cache/?envType=study-plan-v2&envId=top-100-liked
|
|
|
|
type LN struct {
|
|
Key int
|
|
Val int
|
|
Prev *LN
|
|
Next *LN
|
|
}
|
|
|
|
type LRUCache struct {
|
|
length int
|
|
capacity int
|
|
dummyHead *LN
|
|
dummyTail *LN
|
|
kv map[int]*LN
|
|
}
|
|
|
|
func Constructor(capacity int) LRUCache {
|
|
head := &LN{}
|
|
tail := &LN{}
|
|
head.Next = tail
|
|
tail.Prev = head
|
|
return LRUCache{
|
|
length: 0,
|
|
capacity: capacity,
|
|
dummyHead: head,
|
|
dummyTail: tail,
|
|
kv: make(map[int]*LN, capacity),
|
|
}
|
|
}
|
|
|
|
func (this *LRUCache) removeNode(node *LN) {
|
|
node.Prev.Next = node.Next
|
|
node.Next.Prev = node.Prev
|
|
}
|
|
|
|
func (this *LRUCache) addToHead(node *LN) {
|
|
node.Next = this.dummyHead.Next
|
|
node.Prev = this.dummyHead
|
|
this.dummyHead.Next.Prev = node
|
|
this.dummyHead.Next = node
|
|
}
|
|
|
|
func (this *LRUCache) Get(key int) int {
|
|
if node, ok := this.kv[key]; ok {
|
|
this.removeNode(node)
|
|
this.addToHead(node)
|
|
return node.Val
|
|
}
|
|
return -1
|
|
}
|
|
|
|
func (this *LRUCache) Put(key int, value int) {
|
|
if node, ok := this.kv[key]; ok {
|
|
node.Val = value
|
|
this.removeNode(node)
|
|
this.addToHead(node)
|
|
return
|
|
}
|
|
if this.length >= this.capacity {
|
|
lru := this.dummyTail.Prev
|
|
this.removeNode(lru)
|
|
delete(this.kv, lru.Key)
|
|
} else {
|
|
this.length++
|
|
}
|
|
newNode := &LN{Key: key, Val: value}
|
|
this.addToHead(newNode)
|
|
this.kv[key] = newNode
|
|
}
|
|
|
|
func Test1(t *testing.T) {
|
|
lRUCache := Constructor(2)
|
|
lRUCache.Put(1, 1)
|
|
lRUCache.Put(2, 2)
|
|
fmt.Println(lRUCache.Get(1))
|
|
lRUCache.Put(3, 3)
|
|
fmt.Println(lRUCache.Get(2))
|
|
lRUCache.Put(4, 4)
|
|
fmt.Println(lRUCache.Get(1))
|
|
fmt.Println(lRUCache.Get(3))
|
|
fmt.Println(lRUCache.Get(4))
|
|
}
|