package main

import "fmt"

func main() {
    c := Constructor(2)
    c.Put(1, 1)           // 1: 1
    c.Put(2, 2)           // 1: 2->1
    fmt.Println(c.Get(1)) // 1: 1->2
    c.Put(3, 3)           // 2 失效
    fmt.Println(c.Get(2)) // -1
    fmt.Println(c.Get(3)) // 1: 3->1
    c.Put(4, 4)           // 1 失效 // 1: 4->3
    fmt.Println(c.Get(1)) // -1
    fmt.Println(c.Get(3)) // 1: 3->4
    fmt.Println(c.Get(4)) // 1: 4->3
}

type LFUCache struct {
    capacity int
    minFreq  int
    items    map[int]*Node
    freqs    map[int]*List
}

func Constructor(capacity int) LFUCache {
    return LFUCache{
        capacity: capacity,
        minFreq:  0,
        items:    make(map[int]*Node),
        freqs:    make(map[int]*List),
    }
}

func (this *LFUCache) Get(k int) int {
    // 未命中
    node, ok := this.items[k]
    if !ok {
        return -1
    }

    // 命中
    this.freqs[node.freq].Remove(node) // 挪动到下一频率梯队
    node.freq++
    if _, ok := this.freqs[node.freq]; !ok {
        this.freqs[node.freq] = NewList()
    }
    newNode := this.freqs[node.freq].Prepend(node)
    this.items[k] = newNode
    // 注意判断最小梯队
    if this.freqs[this.minFreq].Size() == 0 {
        this.minFreq++
    }
    return node.val
}

func (this *LFUCache) Put(key, value int) {
    if this.capacity == 0 {
        return
    }
    // 命中
    if val := this.Get(key); val != -1 {
        this.items[key].val = value
        return
    }

    // 缓存已满
    if this.capacity == len(this.items) {
        oldest := this.freqs[this.minFreq].Tail()
        this.freqs[this.minFreq].Remove(oldest)
        delete(this.items, oldest.key)
    }

    node := &Node{key: key, val: value, freq: 1}
    this.items[key] = node
    if _, ok := this.freqs[1]; !ok {
        this.freqs[1] = NewList()
    }
    this.freqs[1].Prepend(node)
    this.minFreq = 1
}

type Node struct {
    key        int
    val        int
    freq       int
    prev, next *Node
}

type List struct {
    head, tail *Node
    size       int
}

func NewList() *List {
    return new(List)
}

func (l *List) Prepend(node *Node) *Node {
    if l.head == nil {
        l.head = node
        l.tail = node
    } else {
        node.prev = nil
        node.next = l.head
        l.head.prev = node
        l.head = node
    }
    l.size++
    return l.head
}

func (l *List) Remove(node *Node) *Node {
    if node == nil {
        return nil
    }

    prev, next := node.prev, node.next
    if prev == nil {
        l.head = next
    } else {
        prev.next = next
    }

    if next == nil {
        l.tail = prev
    } else {
        next.prev = prev
    }

    node.prev, node.next = nil, nil
    l.size--
    return node
}

func (l *List) Size() int {
    return l.size
}

func (l *List) Tail() *Node {
    return l.tail
}
最后编辑: kuteng  文档更新时间: 2021-06-05 10:16   作者:kuteng