| 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);
 
-  */
 
 
  |