LRU cache
LFU:
import collections
d1 = collections.OrderedDict()
OrderedDict
使用dict时,key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
如果想要保持key的顺序,可以使用OrderedDict。OrderedDict的key会按照插入的顺序排列,不是key本身排序。
OrderedDict.popitem()
OrderedDict.popitem()有一个可选参数last(默认为True),当last为True时它从OrderedDict中删除最后一个键值对并返回该键值对,当last为False时它从OrderedDict中删除第一个键值对并返回该键值对。
错误写法:
class LRUCache:
def __init__(self, capacity: int):
self.dict = collections.OrderedDict()
self.remain = capacity
def get(self, key: int) -> int:
if key in self.dict:
return self.dict[key]
return -1
def put(self, key: int, value: int) -> None:
if key in self.dict:
self.dict[key] = value
else:
if self.remain > 0:
self.dict[key] = value
self.remain -= 1
else:
self.dict.popitem(last = False)
self.dict[key] = value
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
问题:无论这个key在字典里是否存在,即使是存在的情况,每次它被用了之后一定是放在最上层的。所以我们要先删除.pop了之后再加入。用orderedlist可以让键值对加入到顶部。
last = True或者(popitem())的时候是弹出最尾部,也就是最近加入的,不符合题意
last = False (popitem(last = Flase)) 的时候是弹出最顶部,也就是最早加入的。符合题意
正确写法:
class LRUCache:
def __init__(self, capacity: int):
self.dict = collections.OrderedDict()
self.remain = capacity
def get(self, key: int) -> int:
if key in self.dict:
value = self.dict.pop(key)
self.dict[key] = value
return value
return -1
def put(self, key: int, value: int) -> None:
if key in self.dict:
self.dict.pop(key)
else:
if self.remain > 0:
self.remain -= 1
else:
self.dict.popitem(last = False)
self.dict[key] = value
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
我存在的问题: 对dict不熟练,heap,hashmap,二叉树,链表都不熟练,需要再加强练习,再做一遍
bloom filter 布隆过滤器
先过滤一遍判断元素在不在,再去cache里面查询这个元素
如果检索不在,那一定不在。如果检索在的话,有误识别率
牺牲了一定识别率,用二进制查询非常快。
添加x,y,z三个元素,然后用映射函数分别映射到相应的二进制位,并把位置置1
去查询元素的时候,例如查询w元素,如果映射函数相应的位数都是1的话,那么说明这个w存在在这个元素里。
如果没有都为1,那么一定不在
判断B的时候,误识别率。因为其实是AC在里面。 这是错误的
所以去文件库里面查询B,看能不能查出来。
布隆过滤器只是查一下。和cache一样,跟门神一样,后面都是数据的权威机构,例如sram,磁盘等
现实案例:
1.比特币:
Redis VS BloomFilter 前者:内存的缓存,把元素暂存在内存中,可以直接从内存返回 后者:看是否存在。不在就不查了 两者都可以加速,减轻负担
比特币:
看哪个区块的bloom filter存在。存在再去查找相关的交易记录,再返回到手机上钱包的客户端。
分配和验证子任务是否在某台机器上存在