[Golang修仙之路] 算法专题:LRU & LFU

24 阅读1分钟

1. list 库的使用

  • list.Len() // 获取双向链表长度
  • list.Element.Value // 是一个 interface{}
  • list.PushBack(interface{}) *Element // 注意有返回值,这个返回值要用到的
  • list.MoveToBack(e *Element) // 移动到链表尾部
  • value := l.Remove(e *Element) interface{} // 删除元素并返回其值,O(1)
  • list.List // 双向链表类型
  • l := list.New() // 创建新的空链表, 返回的是指针

2. LRU

  • 尾部插入,头部删除
  • 容量 + map + list
type LRUCache struct {
    cap int
    cache map[int]*list.Element
    l *list.List
}

type entry struct {
    key int
    val int
}

func Constructor(capacity int) LRUCache {
    return LRUCache{
        cap: capacity,
        cache: make(map[int]*list.Element),
        l: list.New(),
    }
}

func (this *LRUCache) Get(key int) int {
    node, ok := this.cache[key]
    if ok {
        this.l.MoveToBack(node)
        return node.Value.(*entry).val
    }
    return -1
}

func (this *LRUCache) Put(key int, value int)  {
    node, ok := this.cache[key]
    if ok {
        node.Value.(*entry).val = value
        this.l.MoveToBack(node)
        return
    }

    newNode := this.l.PushBack(&entry{key, value})
    this.cache[key] = newNode

    if this.l.Len() > this.cap {
        head := this.l.Front()
        delete(this.cache, head.Value.(*entry).key)
        this.l.Remove(head)
    }
}