1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
| package main
type LFUCache struct { cache map[int]*Node freq map[int]*DoubleList ncap, size, minFreq int }
func (this *LFUCache) IncrFreq(node *Node) { _freq := node.freq this.freq[_freq].RemoveNode(node) if this.minFreq == _freq && this.freq[_freq].IsEmpty() { this.minFreq++ delete(this.freq, _freq) } node.freq++
if this.freq[node.freq] == nil { this.freq[node.freq] = createDL() } this.freq[node.freq].AddFirst(node) }
func Constructor(capacity int) LFUCache { return LFUCache{ cache: make(map[int]*Node), freq: make(map[int]*DoubleList), ncap: capacity, } }
func (this *LFUCache) Get(key int) int { if node, ok := this.cache[key]; ok { this.IncrFreq(node) return node.val }
return -1 }
func (this *LFUCache) Put(key int, value int) { if this.ncap == 0 { return } if node, ok := this.cache[key]; ok { node.val = value this.IncrFreq(node) } else { if this.size >= this.ncap { node := this.freq[this.minFreq].RemoveLast() delete(this.cache, node.key) this.size-- } x := &Node{key: key, val: value, freq: 1} this.cache[key] = x if this.freq[1] == nil { this.freq[1] = createDL() } this.freq[1].AddFirst(x) this.minFreq = 1 this.size++ } }
type Node struct { key, val, freq int prev, next *Node }
type DoubleList struct { tail, head *Node }
func createDL() *DoubleList { head, tail := &Node{}, &Node{} head.next, tail.prev = tail, head
return &DoubleList{ tail: tail, head: head, } }
func (this *DoubleList) IsEmpty() bool { return this.head.next == this.tail }
func (this *DoubleList) AddFirst(node *Node) { node.next = this.head.next node.prev = this.head
this.head.next.prev = node this.head.next = node }
func (this *DoubleList) RemoveNode(node *Node) { node.next.prev = node.prev node.prev.next = node.next
node.next = nil node.prev = nil }
func (this *DoubleList) RemoveLast() *Node { if this.IsEmpty() { return nil }
lastNode := this.tail.prev this.RemoveNode(lastNode)
return lastNode }
|