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:
map and doubly linked list.
https://www.code-recipe.com/post/lru-cache
class LRUCache:
def __init__(self, capacity: int):
class node:
def __init__(self, key, val, L=None, R=None):
self.key = key
self.val = val
self.L = L
self.R = R
class dlink:
def __init__(self):
self.head = node(-1, -1)
self.tail = node(-1, -1)
self.head.R = self.tail
self.tail.L = self.head
self.len = 0
def add_node(self, key, val):
new_node = node(key, val, self.head, self.tail)
new_node.L = self.head
new_node.R = self.head.R
self.head.R.L = new_node
self.head.R = new_node
self.len += 1
return new_node
def del_node(self, now_node=None):
if not now_node:
now_node = self.tail.L
now_node.L.R = now_node.R
now_node.R.L = now_node.L
self.len -= 1
return now_node
self.len = capacity
self.map = {}
self.lik = dlink()
def get(self, key: int) -> int:
if key in self.map:
index = self.lik.del_node(self.map[key])
del self.map[index.key]
new_node = self.lik.add_node(index.key, index.val)
self.map[key] = new_node
return new_node.val
return -1
def put(self, key: int, value: int) -> None:
if key in self.map:
self.lik.del_node(self.map[key])
del self.map[key]
new_node = self.lik.add_node(key, value)
self.map[key] = new_node
if len(self.map) > self.len:
now_node = self.lik.del_node() # Remove last node
del self.map[now_node.key]
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)