Leetcode上看到这题,感觉是个很有意思的题目,好好整一整
LRU (Least recently used,最近最少使用)
一个经典的使用场景:CPU的高速缓存 
1.基于哈希表和双向链表实现LRU 整体的设计思路是,可以使用 HashMap 存储 key,这样可以做到 save 和 get key的时间都是 O(1),而 HashMap 的 Value 指向双向链表实现的 LRU 的 Node 节点。
有点不太能理解,
 
貌似我想的并不是很清楚 头有点大
双向链表的好处在哪呢
冷静一下
先上我这个很挫的代码 。复杂度应该都是O(n)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 class  LRUCache :    def  __init__ (self, capacity: int  ):         self.max_capacity=capacity         self.dict_struct=dict ()         self.last_used=list ()     def  get (self, key: int  ) -> int :                  if  key in  self.dict_struct:             if  key in  self.last_used:                 if  self.last_used[-1 ]==key:                     return  self.dict_struct[key]                                  to_pop=-1                  for  index,value in  enumerate (self.last_used):                     if  value==key:                         to_pop=index                         break                                                    self.last_used.pop(to_pop)                 self.last_used.append(key)                          else :                 if  len (self.last_used)==self.max_capacity:                     self.last_used.pop(0 )                 self.last_used.append(key)             return  self.dict_struct[key]         else :             return  -1                   def  put (self, key: int , value: int  ) -> None :                  if  key in  self.dict_struct:             self.dict_struct[key]=value             to_pop=-1              for  index,value in  enumerate (self.last_used):                 if  value==key:                     to_pop=index                     break                               self.last_used.pop(to_pop)             self.last_used.append(key)             return          if  len (self.last_used)+1 <=self.max_capacity:             pass          else :             del  self.dict_struct[self.last_used[0 ]]             self.last_used.pop(0 )         self.dict_struct[key]=value                 self.last_used.append(key) 
麻烦点就在于:
犯困 搞不明白啊。
二战LRU
先把设计思路搞清晰,一切就都明朗了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 读 		-------数据不存在: return  -1  		-------数据存在: 将数据移动到头(这边设定越靠近头数据越新) 返回数据  写 数据是否存在->               	--存在key:定位,修改值,移动到头                 |                 | 不存在key: 								|--------容量达到上限:那就把尾巴的删了 同时对应hashtable里的数据也得删再往头那里写。   							|	-------容量未达上限:未达上限就只管往头那里写就完了            hashtable doubleLinkedlist   key: 对应值    还有一个麻烦点就在于双向链表的实现 注意一下细节.只有当缓存没满时,size在变化 还有就是注意添加的是cache在添加和删除的时候变化 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 class  DLinkListNode :    def  __init__ (self,key=0 ,value=0  ):         self.key=key         self.value=value         self.prev=None          self.next =None  class  LRUCache :    def  __init__ (self, capacity: int  ):         self.cache=dict ()                  self.tail=DLinkListNode()         self.head=DLinkListNode()         self.head.next =self.tail         self.tail.prev=self.head         self.capacity=capacity         self.size=0      def  get (self, key: int  ) -> int :         if  key not  in  self.cache:             return  -1          node = self.cache[key]         self.moveToHead(node)         return  node.value     def  put (self, key: int , value: int  ) -> None :         if  key not  in  self.cache:                          node = DLinkListNode(key,value)             self.cache[key]=node             self.addToHead(node)             self.size+=1              if  self.size>self.capacity:                 removed = self.removeTail()                                  self.cache.pop(removed.key)                 self.size-=1          else :             node=self.cache[key]             node.value=value             self.moveToHead(node)     def  addToHead (self,node ):                  head_next = self.head.next          node.prev=self.head         node.next =head_next         head_next.prev=node         self.head.next =node     def  removeNode (self,node ):         node.prev.next =node.next          node.next .prev=node.prev          def  moveToHead (self,node ):         self.removeNode(node)         self.addToHead(node)     def  removeTail (self ):         node = self.tail.prev         self.removeNode(node)         return  node 
操作还是封装在LRU里的
LRU果然没有经过测试的东西就是不可靠的。
有机会应该走一走单元测试,找点感觉。
Redis的LRU实现 参考