LeetCode-in-All

146. LRU Cache

Medium

Design a data structure that follows the constraints of a Least Recently Used (LRU) cache.

Implement the LRUCache class:

The functions get and put must each run in O(1) average time complexity.

Example 1:

Input [“LRUCache”, “put”, “put”, “get”, “put”, “get”, “put”, “get”, “get”, “get”] [[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]

Output: [null, null, null, 1, null, -1, null, -1, 3, 4]

Explanation:

LRUCache lRUCache = new LRUCache(2);

lRUCache.put(1, 1); // cache is {1=1}

lRUCache.put(2, 2); // cache is {1=1, 2=2}

lRUCache.get(1); // return 1

lRUCache.put(3, 3); // LRU key was 2, evicts key 2, cache is {1=1, 3=3}

lRUCache.get(2); // returns -1 (not found)

lRUCache.put(4, 4); // LRU key was 1, evicts key 1, cache is {4=4, 3=3}

lRUCache.get(1); // return -1 (not found)

lRUCache.get(3); // return 3

lRUCache.get(4); // return 4

Constraints:

Solution

import "container/list"

type KeyValue struct {
	key int
	val int
}

type LRUCache struct {
	m        map[int]*list.Element
	q        *list.List
	capacity int
}

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

func (this *LRUCache) Get(key int) int {
	if n, ok := this.m[key]; ok {
		this.q.MoveToFront(n)
		return n.Value.(KeyValue).val
	}
	return -1
}

func (this *LRUCache) Put(key int, value int) {
	kv := KeyValue{key, value}

	if n, ok := this.m[key]; ok {
		n.Value = kv
		this.q.MoveToFront(n)
		this.m[key] = n
	} else {
		this.m[key] = this.q.PushFront(kv)
	}

	if len(this.m) > this.capacity {
		delete(this.m, this.q.Back().Value.(KeyValue).key)
		this.q.Remove(this.q.Back())
	}
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * obj := Constructor(capacity);
 * param_1 := obj.Get(key);
 * obj.Put(key,value);
 */