LRU Cache
Description
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get
and put
.
get(key)
- Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
put(key, value)
- Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
The cache is initialized with a positive capacity.
Follow up:
Could you do both operations in O(1)
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); lRUCache.put(2, 2); lRUCache.get(1); // return 1 lRUCache.put(3, 3); // evicts key 2 lRUCache.get(2); // returns -1 (not found) lRUCache.put(4, 4); // evicts key 1 lRUCache.get(1); // return -1 (not found) lRUCache.get(3); // return 3 lRUCache.get(4); // return 4
Constraints:
1 <= capacity <= 3000
0 <= key <= 3000
0 <= value <= 104
- At most
3 * 104
calls will be made toget
andput
.
Solution(javascript)
// class Node {
// constructor(key, val) {
// this.val = val
// this.prev = null
// this.key = key
// this.next = null
// }
// }
// /**
// * @param {number} capacity
// */
// const LRUCache = function (capacity) {
// this.capacity = capacity
// this.size = 0
// this.map = {}
// this.head = new Node()
// this.tail = new Node()
// this.head.next = this.tail
// }
// /**
// * @param {number} key
// * @return {number}
// */
// LRUCache.prototype.get = function (key) {
// const node = this.map[key]
// if (node === undefined) {
// return -1
// }
// this.delete(node)
// this.insert(node)
// return node.val
// }
// /**
// * @param {number} key
// * @param {number} value
// * @return {void}
// */
// LRUCache.prototype.put = function (key, value) {
// if (this.capacity < 1) {
// return
// }
// let node = this.map[key]
// if (node !== undefined) {
// node.val = value
// this.delete(node)
// this.insert(node)
// } else {
// node = new Node(key, value)
// this.insert(node)
// }
// }
// LRUCache.prototype.delete = function (node) {
// delete this.map[node.key]
// const prevNode = node.prev
// const nextNode = node.next
// prevNode.next = nextNode
// nextNode.prev = prevNode
// this.size -= 1
// }
// LRUCache.prototype.insert = function (node) {
// this.size += 1
// node.next = this.head.next
// node.next.prev = node
// node.prev = this.head
// this.head.next = node
// this.map[node.key] = node
// if (this.size > this.capacity) {
// this.delete(this.tail.prev)
// }
// }
/**
* @param {number} capacity
*/
const LRUCache = function (capacity) {
this.capacity = capacity
this.map = new Map()
}
/**
* @param {number} key
* @return {number}
*/
LRUCache.prototype.get = function (key) {
if (!this.map.has(key)) {
return -1
}
const value = this.map.get(key)
this.map.delete(key)
this.map.set(key, value)
return value
}
/**
* @param {number} key
* @param {number} value
* @return {void}
*/
LRUCache.prototype.put = function (key, value) {
if (this.map.has(key)) {
this.map.delete(key)
}
this.map.set(key, value)
if (this.map.size > this.capacity) {
this.map.delete(this.map.keys().next().value)
}
}