146. LRU缓存机制

开发者 2024-9-15 09:09:00 117 0 来自 中国
146. LRU缓存机制(难度:中等)

标题链接:https://leetcode-cn.com/problems/lru-cache/
标题描述:

运用你所把握的数据结构,计划和实现一个 LRU (近来最少使用) 缓存机制。它应该支持以下使用: 获取数据 get 和 写入数据 put 。
获取数据 get(key) - 假如关键字 (key) 存在于缓存中,则获取关键字的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 假如关键字已经存在,则变动其数据值;假如关键字不存在,则插入该组「关键字/值」。当缓存容量到达上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
进阶:
你是否可以在 O(1) 时间复杂度内完成这两种使用?
示例:
LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );cache.put(1, 1);cache.put(2, 2);cache.get(1);       // 返回  1cache.put(3, 3);    // 该使用会使得关键字 2 取消cache.get(2);       // 返回 -1 (未找到)cache.put(4, 4);    // 该使用会使得关键字 1 取消cache.get(1);       // 返回 -1 (未找到)cache.get(3);       // 返回  3cache.get(4);       // 返回  4算法分析:

由于标题要求时间复杂度为O(1),以是我的必要的数据结构要符合下述几个条件:
(1)查询一个结点是否已经存在缓存区中
(2)缓存区溢出,必要将最早未访问的结点举行删除
(3)缓存区的某个结点被再次访问,必要将该节点标志为最新的结点。
(4)对缓存区中的结点举行排序或做标志,记录他们最新访问的序次。
(5)在插入大概移动结点
在上述全部使用中,都要满足时间复杂度为O(1)。
题目一:办理记录结点序次:双向链表
起首,分析必要记录缓存区中全部结点的最新访问序次,有三种数据结构:
(1)数组,使用数组可以将缓存区中的结点按照访问序次举行排序,但是,在访问了之前缓存区中的结点,必要将之前的结点举行移动到数组末了,显然必要移动数组后面的全部结点,不符合O(1)的时间复杂度。因此不满足。
(2)单链表,使用链表可以将缓存区中的结点按照访问序次举行排序,我们在写入数据时,如果新数据,则直接插入到链表末了;如果缓存区中已经存在的结点,则将其指针举行移动,将该节点作为末了结点,时间复杂度都是O(1)。但是在举行指针移动时,必要之间该节点的前置和后置结点,后置结点可以之间获取到,但是前置结点就必要遍历整个链表举行获取,因此,单链表也是不符合条件的。
(3)双向链表,上述分析,应该可以很容易的想到双向链表,使用双向链表可以对前置结点举行记录。
题目二:办理判断新节点是否已经在缓存区
由于时间复杂度限定为O(1),必要在一堆结点中一步判断出是否存在该节点,不消想,肯定是hash表。
因此,我们的数据结构定为:hash表 + 双向链表
解法一:使用JDK中的LinkedHashMap

在JDK中存在一种数据结构,叫做LinkedHashMap,他的底层结构就是HashMap + 双向链表,他是在HashMap的根本上,举行了扩展,可以通过两种方式举行排序:

  • 按照插入序次举行排序
  • 按照读取的序次举行排序(这道题我们想要的)
他的底层是通过一个双向链表来维持这种排序的,在每次插入、删除,都会调用函数举行=双向链表的维护。下面是LinkedHashMap中三个方法:
(1)void afterNodeAccess(Node<K,V> p) { }
其作用是在访问元素之后,将该元素放到双向链表的尾巴处,该方法只有在按照读取序次排序才会实行。
(2)void afterNodeRemoval(Node<K,V> p) { }
其作用是在HashMap中删除元素之后,将元素从双向链表中删除。
(3)void afterNodeInsertion(boolean evict) { }
其作用是在新插入元素之后,判断是否必要移除最久未使用的结点(也就是双向链表中排在最前面的结点)。也是我们这道题中必须的方法。
LinkedHashMap中的构造函数:
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-22 16:54, Processed in 0.160490 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表