文章目录

  • 题目描述
  • 思路 & 代码
    • LinkedHashMap 的写法

题目描述

  • 大名鼎鼎的超高频面试题
  • 太感动,在这道题上花了太多时间了,今天终于补上博客了TvT

思路 & 代码

  • 结构用的是:双向链表 + 哈希表。可以满足O(1)时间复杂度
  • put():key存在则delete,然后再put;否则直接put
  • get():key存在则保存值,然后put(放到前面,顺带删除原结点,复用代码)
  • 查找的O(1):通过HashMap实现,以及伪尾结点(removeLast)
  • 删除的O(1):通过双向链表实现
  • tips:伪头结点、伪尾结点(避免了检查相邻结点是否为null,不装入map)
class LRUCache {// 自己写双向链表结点类class DoubleListNode{int val;int key;DoubleListNode pre;DoubleListNode next;DoubleListNode(){}DoubleListNode(int keyy, int value){ key = keyy; val = value; }}int cap;int size;// 哈希表直接套用现成的 HashMapHashMap<Integer, DoubleListNode> map;// 使用伪头部、首部,便于省去判断DoubleListNode head,tail;public LRUCache(int capacity) {cap = capacity;size = 0;map = new HashMap();// 使用伪头部 & 伪首部:增删不用判断相邻为空// key和head、tail重复的情况怎么办:其实head和tail根本就没有放进map里head = new DoubleListNode();tail = new DoubleListNode();head.next = tail;tail.pre = head;}public int get(int key) {// 哈希查找O(1)DoubleListNode now = map.get(key);if(now != null){int getNum = now.val;// 把查找结点置于headput(now.key, now.val);return getNum;}return -1;}// 删尾 & 删中间兼容void removeNode(DoubleListNode removeN){size--;removeN.pre.next = removeN.next;removeN.next.pre = removeN.pre;// 记得把 map 的也删了~map.remove(removeN.key,removeN);}public void put(int key, int value) {// 更新的情况,删掉之前结点if(map.containsKey(key)){removeNode(map.get(key));}// 添加到headDoubleListNode nowN = new DoubleListNode(key, value);nowN.pre = head;nowN.next = head.next;head.next.pre = nowN;head.next = nowN;size++;// 记得加入 map~map.put(key,nowN);// Cache满,删除尾结点if(size > cap){removeNode(tail.pre);}}
}

LinkedHashMap 的写法

  • Java 自带的“外挂类”:维护插入顺序的哈希表
class LRUCache {private int cap;private Map<Integer, Integer> map = new LinkedHashMap<>();public LRUCache(int capacity) {this.cap = capacity;}public int get(int key) {if(map.keySet().contains(key)) {int value = map.get(key);map.remove(key);map.put(key, value);return value;}return -1;}public void put(int key, int value) {// Case 1: 重复插入,删除重复节点if(map.keySet().contains(key)) {map.remove(key);}// Case 2: 满了,删除第一个节点(LinkedHashMap 维护插入顺序)if(map.size() == cap) {Iterator<Map.Entry<Integer, Integer>> iterator = map.entrySet().iterator();iterator.next();iterator.remove();}map.put(key, value);}
}

【LeetCode笔记】146. LRU缓存机制(Java、双向链表、哈希表)相关推荐

  1. LRU 缓存机制实现:哈希表 + 双向链表

    算法详解 LRU 缓存机制可以通过哈希表辅以双向链表实现,我们用一个哈希表和一个双向链表维护所有在缓存中的键值对. 双向链表按照被使用的顺序存储了这些键值对,靠近头部的键值对是最近使用的,而靠近尾部的 ...

  2. 【LeetCode】146. LRU缓存机制

    题目描述 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制. 它应该支持以下操作:获取数据 get 和写入数据 put . 获取数据 get(key) - 如果密钥 (key ...

  3. Leetcode 146. LRU缓存机制【哈希表 [哈希表存储每个元素在双向链表中的指针]+双向链表】

    文章目录 问题描述 解题报告 实验代码 参考资料 问题描述 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . ...

  4. Java实现 LeetCode 146 LRU缓存机制

    146. LRU缓存机制 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - ...

  5. 146. LRU 缓存机制

    146. LRU 缓存机制 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 . 实现 LRUCache 类: LRUCache(int capacity) 以正整数作为容量 ...

  6. LeetCode 146. LRU缓存机制(哈希链表)

    文章目录 1. 题目信息 2. 解题 2.1 手动实现list 2.2 使用内置list 1. 题目信息 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作 ...

  7. LeetCode —— 146. LRU缓存机制(Python)

    运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果关键字 (key) 存 ...

  8. C++实现LRU算法(LeetCode 146 LRU缓存机制)

    LRU算法: LRU算法(Least Recently Used)是一种缓存淘汰策略,最近使用的数据是有用的, 如果缓存满了,删除最久没用过的数据 LRU算法描述: (1)设置缓存大小 (2)get: ...

  9. [leetcode]146. LRU缓存机制

    1.LRU(最近最少使用)缓存机制: https://baike.baidu.com/item/LRU/1269842?fr=aladdin 2.用到的数据结构: struct Value {int ...

最新文章

  1. 手把手教你如何做建模竞赛(baseline代码讲解)
  2. 使用MASM04 - Win32汇编语言012
  3. time模块及datetime模块常用方法讲解
  4. JavaScript基础学习--05自定义属性、索引值
  5. 液滴型单细胞测序技术比较(二)
  6. 吃奶酪(洛谷-P1433)
  7. linux下oracle中文乱码问题的解决
  8. oracle odac 客户端 区别,ODAC使用指南 (一)ODAC常见问题集
  9. 博客起航:为什么应该写博客
  10. Oracle删除数据消耗时间大吗,oracle 删除大量数据的方法
  11. distribute by控制分区文件数
  12. Python通过标点符号断句
  13. 输出4+44+444+4444
  14. 打印菱形图案c语言pta,C语言的考试题型
  15. Ubuntu系统下打开chm文件
  16. 操作成功的提示信息动态添加
  17. Emacs 从入门到精通
  18. 内存调试: GC_CONCURRENT freed
  19. 寒江独钓(2):串口的过滤
  20. 微信小程序云开发支付

热门文章

  1. docker port如何增加端口_docker部署redis实战
  2. python定义类时括号_为什么在定义类时括号是可选的,而在定义函数时括号是必需的?...
  3. mysql count里面能加条件吗_select count(1) 和 count(*),哪个性能更好?
  4. 西华大学c语言期末成绩占比例,期末成绩开始录入!优秀率一般不得超过20%
  5. 卷积在计算机中实现+pool作用+数据预处理目的+特征归一化+理解BN+感受野理解与计算+梯度回传+NMS/soft NMS
  6. 一篇文章搞懂数据仓库:常用ETL工具、方法
  7. MAC OS 命令行使用详解
  8. 【进阶】 --- 多线程、多进程、异步IO实用例子
  9. Cheat Engine 教程( 1 - 9 通关 )
  10. Replace Type Code with State/Strategy(以State/Strategy取代类型码)