当前位置: 首页 > news >正文

LRU cache的实现细节优化——伪结点的技巧

LRU cache的实现是面试常见的题目,思路比较简单,可以参考思路
这个题目在实际面试中容易出错,主要是npe和头节点与尾节点的更新,有没有办法避免这一点呢,这时可以发现伪节点的好处,永远不用更新头尾节点,也不用担心出现npe

在双向链表的实现中,使用一个伪头部(dummy head)和伪尾部(dummy tail)标记界限,这样在添加节点和删除节点的时候就不需要检查相邻的节点是否存在。

代码实现:

import java.util.HashMap;
import java.util.Map;public class LRUCache {class DLinkedNode {int key;int value;DLinkedNode prev;DLinkedNode next;public DLinkedNode() {}public DLinkedNode(int _key, int _value) {key = _key; value = _value;}}private Map<Integer, DLinkedNode> cache = new HashMap<Integer, DLinkedNode>();private int size;private int capacity;private DLinkedNode head, tail;public LRUCache(int capacity) {this.size = 0;this.capacity = capacity;// 使用伪头部和伪尾部节点head = new DLinkedNode();tail = new DLinkedNode();head.next = tail;tail.prev = head;}public int get(int key) {DLinkedNode node = cache.get(key);if (node == null) {return -1;}// 如果 key 存在,先通过哈希表定位,再移到头部moveToHead(node);return node.value;}public void put(int key, int value) {DLinkedNode node = cache.get(key);if (node == null) {// 如果 key 不存在,创建一个新的节点DLinkedNode newNode = new DLinkedNode(key, value);// 添加进哈希表cache.put(key, newNode);// 添加至双向链表的头部addToHead(newNode);++size;if (size > capacity) {// 如果超出容量,删除双向链表的尾部节点DLinkedNode tail = removeTail();// 删除哈希表中对应的项cache.remove(tail.key);--size;}}else {// 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部node.value = value;moveToHead(node);}}private void addToHead(DLinkedNode node) {node.prev = head;node.next = head.next;head.next.prev = node;head.next = node;}private void removeNode(DLinkedNode node) {node.prev.next = node.next;node.next.prev = node.prev;}private void moveToHead(DLinkedNode node) {removeNode(node);addToHead(node);}private DLinkedNode removeTail() {DLinkedNode res = tail.prev;removeNode(res);return res;}
}
http://www.lryc.cn/news/142035.html

相关文章:

  • 【C/C++】父类指针指向子类对象 | 隐藏
  • NSSCTF——Web题目2
  • 从零到富:探索CSGO搬砖项目的无限可能
  • Uniapp中vuex的使用
  • SpringBoot案例-配置文件-参数配置化
  • android系统启动流程之zygote(Native)启动分析
  • Win10上ffmpeg出现Invalid report file level
  • Vue3 中引入液晶数字字体(通常用于大屏设计)
  • 从 Future 到 CompletableFuture:简化 Java 中的异步编程
  • 【ARMv8 SIMD和浮点指令编程】NEON 乘法指令——乘法知多少?
  • Nginx详解 第三部分:Nginx高级配置(附配置实例)
  • postman访问ruoyi后台接口
  • 大数据时代的软件开发实践:利用云计算和AI赋能创新
  • 32、启用 HTTP 响应压缩和编程式配置Web应用
  • DiskCatalogMaker for Mac简单智能快速的磁盘管理工具
  • C语言练习5(巩固提升)
  • SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录(第三天)动态SQL
  • Kaggle(3):Predict CO2 Emissions in Rwanda
  • 【技巧分享】如何获取子窗体选择了多少记录数?一招搞定!
  • Kotlin AQ
  • SpringBoot入门篇2 - 配置文件格式、多环境开发、配置文件分类
  • UOS安装6.1.11内核或4.19内核
  • HiveSQL刷题
  • path路径模块
  • 1.文章复现《热电联产系统在区域综合能源系统中的定容选址研究》(附matlab程序)
  • 【Terraform学习】使用 Terraform 托管 S3 静态网站(Terraform-AWS最佳实战学习)
  • 触发JVM fatal error并配置相关JVM参数
  • 爬虫(bilibili热门课程记录)
  • 14-模型 - 增删改查
  • C#与西门子PLC1500的ModbusTcp服务器通信3--搭建ModbusTcp服务器