Day24-LRU Cache
问题描述:
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?
缓存中存储了一些缓冲的数据,但是缓存的空间是有限的这时我们想要将,最近最少被访问过的元素(LRU)踢出来。而将新的元素或者是访问的元素提到缓存的前面。这就是我们要做的。
实话实说看到这道题我是一点思路都没有而且题目都没怎么读懂,所以我就找了网上的一些大神博客研究了一下。因为基于O(1)的时间复杂度所以要用到双链表进行删除和添加操作,至于查找操作就用到字典(hash表)就可以了。
原理是这样的,我们当执行get函数时,从字典中找这个元素,如果有的话就返回这个值并且将这个元素移到双链表的开头,代表最近访问过的元素,没有的话返回-1.而put操作时我们也是先看有没有这个值,如果有这个值就是将元素移到双链表的开头,并且更新其值。如果没有就在双链表的开头位置添加。而且如果移动完以后,双链表超过缓存的限度了就移除尾部元素。
Example:
LRUCache cache = new LRUCache( 2 /* capacity */ );
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // returns 1
cache.put(3, 3); // evicts key 2
cache.get(2); // returns -1 (not found)
cache.put(4, 4); // evicts key 1
cache.get(1); // returns -1 (not found)
cache.get(3); // returns 3
cache.get(4); // returns 4
class LinkedListNode(object):
def __init__(self, key=None, val=-1):
self.key = key
self.val = val
self.pre = None
self.next = None
class LinkedList(object):
def __init__(self):
self.head = None
self.tail = None
self.size = 0
def appendHead(self, node):
node.next, node.pre = self.head, None
if self.head:
self.head.pre = node
self.head = node
if not self.tail:
self.tail = self.head
self.size += 1
def remove(self, node):
if not node:
return
pre, next = node.pre, node.next
if pre:
pre.next = next
if next:
next.pre = pre
if self.head == node:
self.head = next
if self.tail == node:
self.tail = pre
self.size -= 1
return node
def removeTail(self):
return self.remove(self.tail)
def advance(self, node):
self.remove(node)
self.appendHead(node)
class LRUCache(object):
def __init__(self, capacity):
self.capacity = capacity
self.record = {}
self.linkedList = LinkedList()
def get(self, key):
if key not in self.record:
return -1
self.linkedList.advance(self.record[key])
return self.record[key].val
def put(self, key, value):
if key not in self.record:
node = LinkedListNode(key, value)
self.linkedList.appendHead(node)
self.record[key] = node
if self.linkedList.size > self.capacity:
del self.record[self.linkedList.removeTail().key]
else:
self.record[key].val = value
self.linkedList.advance(self.record[key])