LRU算法
思路
LRU算法,访问/更新/插入都会将数据置于队尾(假设队头淘汰)。
看3种情况的变化:
- 插入:简单置于队尾即可。
- 更新:删除原有节点,新增节点置于队尾。
- 访问:将原节点提至队尾。
除了插入只需要简单接到链表尾部以外,更新和访问都是可能操作链表中间的,所以自然地就需要引入Map来快速找到对应节点。
并且无论是更新的删除原有节点还是访问的将原节点提至队尾,都需要在链表中间删除节点,所以需要双向链表。
首先实现Node类及DoubleList类,然后按照LRU算法思路实现即可。
代码
原始代码
class LRUCache { private int capacity; private DoubleList list; private Map<Integer, Node> map; public LRUCache(int capacity) { this.capacity = capacity; list = new DoubleList(); map = new HashMap<>(); } public int get(int key) { if (!map.containsKey(key)) return -1; Node node = map.get(key); list.remove(node); list.addLast(node); return node.val; } public void put(int key, int value) { Node node = new Node(key, value); // key不存在 if (!map.containsKey(key)) { // 链表大小 == 容量 if (list.size() == capacity) { Node first = list.removeFirst(); int firstkey = first.key; map.remove(first.key); int listsize = list.size(); int mapsize = map.size(); int a = key; } map.put(key, node); list.addLast(node); return; } // key存在 Node oldNode = map.get(key); list.remove(oldNode); map.put(key, node); list.addLast(node); } } class DoubleList { private Node head, tail; private int size; public DoubleList() { head = new Node(0, 0); tail = new Node(0, 0); head.next = tail; tail.pre = head; size = 0; } public void addLast(Node node) { node.pre = tail.pre; node.next = tail; tail.pre.next = node; tail.pre = node; size++; } public void remove(Node node) { node.pre.next = node.next; node.next.pre = node.pre; size--; } public Node removeFirst() { if (head.next == tail) return null; Node first = head.next; remove(first); return first; } public int size() { return size; } } class Node { // key为了方便移出双向链表后,再去删除Map中的键值对 int key; int val; Node pre; Node next; public Node(int key, int val) { this.key = key; this.val = val; } } /** * Your LRUCache object will be instantiated and called as such: * LRUCache obj = new LRUCache(capacity); * int param_1 = obj.get(key); * obj.put(key,value); */
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义