| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 | type listNode struct {	key  int	val  int	cnt  int	prev *listNode	next *listNode}type linkedList struct {	head *listNode	tail *listNode}func newLinkedList() *linkedList {	head, tail := &listNode{}, &listNode{}	head.next = tail	tail.prev = head	li := &linkedList{head, tail}	return li}func (li *linkedList) remove(node *listNode) {	node.prev.next = node.next	node.next.prev = node.prev}type LFUCache struct {	capacity int	size     int	min      int	cache    map[int]*listNode	freq     map[int]*linkedList}func Constructor(capacity int) LFUCache {	var lfu LFUCache	lfu.capacity = capacity	lfu.cache = make(map[int]*listNode)	lfu.freq = make(map[int]*linkedList)	return lfu}func (this *LFUCache) Get(key int) int {	if node, ok := this.cache[key]; ok {		this.touch(node)		return node.val	}	return -1}func (this *LFUCache) Put(key int, value int) {	if this.capacity == 0 {		return	} // Can not put new node.	if node, ok := this.cache[key]; ok {		this.touch(node)		node.val = value		return	} // If the key already exists, touch it and update the value.	if this.size == this.capacity {		li := this.freq[this.min]		delete(this.cache, li.tail.prev.key)		li.remove(li.tail.prev)		if li.head.next == li.tail {			delete(this.freq, this.min)		}		this.size--	} // If the cache is full, remove the last element in the least freq list.	newNode := &listNode{key, value, 1, nil, nil}	this.insert(newNode)	this.cache[key] = newNode	this.min = 1	this.size++ // Then, insert new node.}func (this *LFUCache) insert(node *listNode) {	li := this.freq[node.cnt]	if li == nil {		li = newLinkedList()		this.freq[node.cnt] = li	}	node.next = li.head.next	node.prev = li.head	li.head.next = node	node.next.prev = node}func (this *LFUCache) touch(node *listNode) {	li := this.freq[node.cnt]	li.remove(node)	if li.head.next == li.tail {		delete(this.freq, node.cnt)		if node.cnt == this.min {			this.min++		}	}	node.cnt++	this.insert(node)}/** * Your LFUCache object will be instantiated and called as such: * obj := Constructor(capacity); * param_1 := obj.Get(key); * obj.Put(key,value); */
 |