数据结构与算法之布隆过滤器和LRU缓存

152 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 17 天,点击查看活动详情

作者: 千石
支持:点赞、收藏、评论
欢迎各位在评论区交流

前言

本文内容来自我平时学习的一些积累,如有错误,还请指正

在题目实战部分,我将代码实现和代码解释设置在了解题思路的下方,方便各位作为参考刷题

一些话

本文内容来自我平时学习的一些积累,如有错误,还请指正

前置知识

布隆过滤器

布隆过滤器(Bloom Filter)是一种空间效率很高的数据结构,它用于判断某个元素是否属于某个集合中。它的优点是快速、节省空间,但存在一定的误判率。下面是布隆过滤器的实现和应用。

实现

布隆过滤器的实现包含三个主要部分:哈希函数、位向量和添加/查询操作。以下是它们的详细说明:

  1. 哈希函数: 布隆过滤器通常需要多个哈希函数。哈希函数的作用是将元素映射到位向量上的位置。每个哈希函数都会返回一个整数,该整数用于表示位向量中的一位,因此哈希函数需要确保尽可能均匀地映射元素。
  2. 位向量: 位向量是一个只包含0和1的数组,它的长度通常是一个非常大的质数。当一个元素被添加到布隆过滤器中时,它的哈希值会在位向量中对应的位置上将该位置的值设为1。
  3. 添加/查询操作:添加操作将一个元素插入到布隆过滤器中,而查询操作则判断一个元素是否已经存在于布隆过滤器中。在查询时,哈希函数会返回一组位置,如果这些位置的值都是1,则表示该元素可能在布隆过滤器中。

应用

  1. 网页黑名单: 在搜索引擎中,布隆过滤器可以用来过滤已经被标记为垃圾网站的URL,从而提高搜索结果的质量。
  2. 缓存: 在缓存中,布隆过滤器可以用来判断某个请求的数据是否已经存在于缓存中。如果存在,可以直接返回缓存中的数据,否则需要从数据库中查询数据并将其添加到缓存中。
  3. 数据库去重: 在数据库中,布隆过滤器可以用来去重,以避免重复插入相同的记录。
  4. 分布式系统: 在分布式系统中,布隆过滤器可以用来判断某个数据是否已经存在于某个节点中。如果该数据已经存在,则可以直接返回结果,而不需要将查询请求发送到其他节点中。

LRU Cache

LRU Cache(最近最少使用缓存)是一种缓存算法,它可以用于提高数据访问速度,尤其是在频繁读取数据的情况下。下面是LRU Cache的实现和应用。

实现

LRU Cache的实现包括两个主要部分:哈希表和双向链表。以下是它们的详细说明:

  1. 哈希表: 哈希表用于记录缓存中的数据。它的键值是数据的Key,值是对应的节点指针。
  2. 双向链表: 双向链表用于维护缓存中的数据顺序。每当一个数据被访问时,它会被移到链表头部,以表示它是最近使用的数据。
  3. 添加/查询操作:在添加数据时,如果缓存已满,则需要淘汰最近最少使用的数据。在查询数据时,需要检查缓存中是否存在对应的数据,如果存在则将其移到链表头部,否则返回空值。

应用

  1. 数据库缓存:在数据库中,LRU Cache可以用来缓存常用的数据,从而减少数据库查询的次数和时间。
  2. Web服务器缓存: 在Web服务器中,LRU Cache可以用来缓存常用的网页和资源文件,从而加快网页的加载速度。
  3. 操作系统缓存: 在操作系统中,LRU Cache可以用来缓存常用的文件和数据块,从而减少磁盘IO的次数和时间。
  4. CPU高速缓存: 在CPU中,LRU Cache可以用来缓存最近使用的指令和数据,从而提高CPU的性能和效率。

题目

题目:146. LRU 缓存

image.png

代码实现

class LRUCache:

    def __init__(self, capacity: int):
        self.capacity = capacity
        self.cache = {}
        self.order = []

    def get(self, key: int) -> int:
        if key in self.cache:
            self.order.remove(key)
            self.order.append(key)
            return self.cache[key]
        else:
            return -1

    def put(self, key: int, value: int) -> None:
        if key in self.cache:
            self.order.remove(key)
        elif len(self.cache) == self.capacity:
            del self.cache[self.order[0]]
            del self.order[0]
        self.cache[key] = value
        self.order.append(key)