题目链接:https://leetcode.com/problems/lru-cache/description/
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations:
getandput.
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.Follow up:
Could you do both operations in O(1) time complexity?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
这道题实在是太经典了。之前第一遍做的时候没太当回事,直接使用python自带的OrderDict把问题随便解决了,第二遍做的时候才体会到了这道题的精妙之处。分别考验了你查询时间为O(1)
和插入/移动时间为O(1)的数据结构,which is hashmap and doubly linked list。
具体实现的时候需要自己写一个简化版的Doubly linked list,考虑好把当前node send to tail的各种corner case。其实我的代码实现还是不够简洁,应该可以更granularly的实现,
但实在是懒得再写了。。想了三天已经。。为了debug还自己手动写了dll的打印方法,忽略就好
class Node(object): def __init__(self, key, value): self.key = key self.value = value self.prev = None self.next = None class LRUCache(object): def __init__(self, capacity): """ :type capacity: int """ self.capacity = capacity self.count = 0 self.hm = {} self.head = None self.tail = None def print_llist(self, head): while head: print "key:" + str(head.key) + " " + "value:" + str(head.value) head = head.next def _send_tail(self, update_node): #print self.hm #self.print_llist(self.head) if self.tail == update_node: return if self.head == None and self.tail == None: self.head = self.tail = update_node return if (not update_node.prev) and (not update_node.next): self.tail.next = update_node update_node.prev = self.tail self.tail = update_node return if self.head == update_node: self.head = self.head.next self.head.prev = None update_node.prev = self.tail update_node.next = None self.tail.next = update_node self.tail = update_node else: update_node.prev.next = update_node.next update_node.next.prev = update_node.prev update_node.prev = self.tail update_node.next = None self.tail.next = update_node self.tail = update_node def get(self, key): """ :type key: int :rtype: int """ #print "get" if key in self.hm: self._send_tail(self.hm[key]) return self.hm[key].value else: return -1 def put(self, key, value): """ :type key: int :type value: int :rtype: void """ #print "put" if key in self.hm: self.hm[key].value = value self._send_tail(self.hm[key]) else: new_node = Node(key, value) self.hm[key] = new_node self._send_tail(new_node) if self.count < self.capacity: self.count += 1 else: del_key = self.head.key self.head = self.head.next del self.hm[del_key] # Your LRUCache object will be instantiated and called as such: # obj = LRUCache(capacity) # param_1 = obj.get(key) # obj.put(key,value)
浙公网安备 33010602011771号