01.08.2021
小白一枚,文章仅当日记本记录学习进度 ;)
如被浏览,请多多指教,非常感谢大家纠错与建议!
(因留学顺便练习英语,所以部分用英文笔记,并无他意)
cache : in memory that holds the most recent result; LRU is a common cache algorithm
1. When you see put and get, you shold think of Hashmap immediately which has instant get and put operations
2. When we use something, we want to move it to the front of the cache. We have to use a linked list because Deletions and Intertions are contant time , also because we need ordering becasue Hashmap are unordered, we need a linked list to keep a structure so that we can put things in constant time , most recently used thing will be at the front of our list right after the head , head.next = new_node, when we delete things it will pop it off the tail
Solution 1 - Hashmap + Double linked list (Python)
class Node:
def __init__(self, key=0, value=0):
self.value = value
self.key = key
self.prev = None
self.next = None
class LRUCache:
def __init__(self, capacity: int):
self.cache = dict()
self.capacity = capacity
self.head = Node() # pseudo head node
self.tail = Node() # pseudo tail node
self.head.next = self.tail
self.tail.prev = self.head
self.size = 0
def get(self, key: int):
if key not in self.cache:
return -1
node = self.cache[key]
self.moveToHead(node)
return node.value
def put(self, key, value):
if key not in self.cache:
node = Node(key, value) # create a new node if it does't exist
self.cache[key] = node # add it to Hashmap
self.addToHead(node) # add it to the head
self.size += 1
if self.size > self.capacity:
removedNode = self.removeTail() # delete the tail node from linked list
self.cache.pop(removedNode.key) # delete the pair from Hashmap
self.size -= 1
else:
node = self.cache[key]
node.value = value
self.moveToHead(node)
def moveToHead(self, node):
self.removeNode(node)
self.addToHead(node)
def removeTail(self):
node = self.tail.prev
self.removeNode(node)
return node
def removeNode(self, node):
node.prev.next = node.next
node.next.prev = node.prev
def addToHead(self, node):
node.prev = self.head
node.next = self.head.next
self.head.next.prev = node
self.head.next = node
Solution 2 - OrderdDict (Python)
Leetcode给的solution,不知道OrderedDict可能想不出来。。。
from collections import OrderedDict
class LRUCache(OrderedDict):
def __init__(self, capacity):
"""
:type capacity: int
"""
self.capacity = capacity
def get(self, key):
"""
:type key: int
:rtype: int
"""
if key not in self:
return - 1
self.move_to_end(key)
return self[key]
def put(self, key, value):
"""
:type key: int
:type value: int
:rtype: void
"""
if key in self:
self.move_to_end(key)
self[key] = value
if len(self) > self.capacity:
self.popitem(last = False)
线性:内存连续,可以通过index访问
链式:不连续,不能通过index访问,追加元素方便,遍历会麻烦
1.单链表 linked list - 通过指针(pointer)把节点(node)串起来;root node, head node, tail node; 缺点是remove时间复杂度为O(n),只能单向遍历
2.双链表 double linked list - prev, value, next; remove时间复杂度为O(1), 可以双向遍历