2024-03-19 02:45:09 +08:00

109 lines
2.0 KiB
Go

package main
import "log"
//https://leetcode-cn.com/problems/lru-cache/
//数组形式实现(O(n)),另外可以用双向链表+哈希表实现(O(1))
type LRUCache struct {
capacity int
cache map[int]int
lru []int
head int
tail int
}
func Constructor(capacity int) LRUCache {
return LRUCache{
capacity: capacity,
cache: make(map[int]int),
lru: make([]int, capacity),
head: 0, tail: 0,
}
}
func (this *LRUCache) Get(key int) int {
v, ok := this.cache[key]
if ok {
this.FloatUp(key)
return v
}
return -1
}
func (this *LRUCache) Put(key int, value int) {
this.cache[key] = value
this.FloatUp(key)
}
func (this *LRUCache) FloatUp(key int) {
//查找位
for i := 0; true; i++ {
var pos = this.pos(i + this.tail)
if key == this.lru[pos] {
//提到第一位,前面的后移
for ; true; i++ {
var pos = this.pos(i + this.tail)
if pos == this.head {
//到头了,跳出
break
}
this.lru[pos] = this.lru[this.pos(pos+1)]
}
this.head = this.head - 1
if this.head == -1 {
this.head = this.capacity - 1
}
break
} else if pos == this.head {
//到头了,跳出
break
}
}
var tmp = this.lru[this.tail]
this.head = this.pos(this.head + 1)
this.lru[this.head] = key
//判断是否已满
if this.head == this.tail {
//满,删除最后一位
delete(this.cache, tmp)
this.tail = this.pos(this.tail + 1)
}
}
func (this *LRUCache) pos(pos int) int {
return pos % this.capacity
}
/**
* Your LRUCache object will be instantiated and called as such:
* obj := Constructor(capacity);
* param_1 := obj.Get(key);
* obj.Put(key,value);
*/
func main() {
cache := Constructor(3)
cache.Put(1, 1)
cache.Put(2, 2)
cache.Put(3, 3)
cache.Put(4, 4)
cache.Get(4)
cache.Get(3)
cache.Get(2)
cache.Get(1)
cache.Put(5, 5)
cache.Get(1)
cache.Get(2)
cache.Get(3)
cache.Get(4)
cache.Get(5)
}
func Equal(expected, actual int) {
if expected != actual {
log.Fatalln(expected, "!=", actual)
} else {
log.Println("OK")
}
}