146. LRU 缓存机制

LeetCode-146

题目描述

题解分析

java代码

  1. package com.walegarrett.interview;
  2. /**
  3. * @Author WaleGarrett
  4. * @Date 2021/2/19 8:51
  5. */
  6. import java.util.HashMap;
  7. import java.util.Map;
  8. /**
  9. * 题目描述:运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制 。
  10. * 实现 LRUCache 类:
  11. * LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
  12. * int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
  13. * void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。
  14. * 当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
  15. *  
  16. * 进阶:你是否可以在 O(1) 时间复杂度内完成这两种操作?
  17. */
  18. public class LeetCode_146 {
  19. private DLinkedNode head,tail;//伪头结点和尾结点
  20. private int size,capacity;
  21. private Map<Integer,DLinkedNode> map = new HashMap<>();
  22. public LeetCode_146(int capacity) {
  23. this.size = 0;
  24. this.capacity = capacity;
  25. //创建伪头结点和伪尾结点
  26. head = new DLinkedNode();
  27. tail = new DLinkedNode();
  28. head.next = tail;
  29. tail.pre = head;
  30. }
  31. public int get(int key) {
  32. DLinkedNode node = map.get(key);
  33. if(node == null)
  34. return -1;
  35. //如果key存在,因为这是最新使用的将其移动到头结点
  36. removeToHead(node);
  37. return node.value;
  38. }
  39. public void put(int key, int value) {
  40. DLinkedNode node = map.get(key);
  41. if(node == null){
  42. //如果key不存在,则创建一个新的结点
  43. DLinkedNode newNode = new DLinkedNode(key, value);
  44. map.put(key, newNode);
  45. //添加到链表头部
  46. addToHead(newNode);
  47. ++size;
  48. //判断个数是否超出容量
  49. if(size>capacity){
  50. //删除尾部结点
  51. DLinkedNode tail = removeTail();
  52. //删除哈希表中对应的项
  53. map.remove(tail.key);
  54. --size;
  55. }
  56. }else{
  57. //如果key存在,首先更新哈希表中的value
  58. node.value = value;
  59. map.put(key, node);
  60. //该结点为最近访问的结点,添加到头结点
  61. removeToHead(node);
  62. }
  63. }
  64. /**
  65. * 双向链表的自定义实现
  66. */
  67. class DLinkedNode{
  68. int key,value;
  69. DLinkedNode pre,next;
  70. public DLinkedNode(){}
  71. public DLinkedNode(int _key, int _value){key = _key; value=_value;}
  72. }
  73. /**
  74. * 将新结点放置到头结点
  75. * @param node
  76. */
  77. private void addToHead(DLinkedNode node){
  78. node.pre = head;
  79. node.next = head.next;
  80. head.next.pre = node;
  81. head.next = node;
  82. }
  83. /**
  84. * 移除当前结点
  85. * @param node
  86. */
  87. private void removeNode(DLinkedNode node){
  88. node.pre.next = node.next;
  89. node.next.pre = node.pre;
  90. }
  91. /**
  92. * 将当前结点移动到头结点
  93. * @param node
  94. */
  95. private void removeToHead(DLinkedNode node){
  96. removeNode(node);
  97. addToHead(node);
  98. }
  99. /**
  100. * 删除尾结点
  101. */
  102. private DLinkedNode removeTail(){
  103. DLinkedNode realTail = tail.pre;
  104. removeNode(realTail);
  105. return realTail;
  106. }
  107. }

复杂度分析

146. LRU 缓存机制 + 哈希表 + 自定义双向链表的更多相关文章

  1. 力扣 - 146. LRU缓存机制

    目录 题目 思路 代码 复杂度分析 题目 146. LRU缓存机制 思路 利用双链表和HashMap来解题 看到链表题目,我们可以使用头尾结点可以更好进行链表操作和边界判断等 还需要使用size变量来 ...

  2. 【golang必备算法】 Letecode 146. LRU 缓存机制

    力扣链接:146. LRU 缓存机制 思路:哈希表 + 双向链表 为什么必须要用双向链表? 因为我们需要删除操作.删除一个节点不光要得到该节点本身的指针,也需要操作其前驱节点的指针,而双向链表才能支持 ...

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

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

  4. 【力扣】146. LRU缓存机制

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

  5. [Leetcode]146.LRU缓存机制

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

  6. Leetcode 146. LRU 缓存机制

    前言 缓存是一种提高数据读取性能的技术,在计算机中cpu和主内存之间读取数据存在差异,CPU和主内存之间有CPU缓存,而且在内存和硬盘有内存缓存.当主存容量远大于CPU缓存,或磁盘容量远大于主存时,哪 ...

  7. 146. LRU缓存机制

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

  8. leetcode:146. LRU缓存机制

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

  9. LeetCode 146. LRU缓存机制(LRU Cache)

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

随机推荐

  1. WIN7使用msg命令发送消息心得

    昨天搞了一下午+一晚上,终于捣鼓出了一些奇奇怪怪的操作,成功发送了消息. 应实验要求,博主有幸在家里搞到了两台win7,其他的系统是不是这么操作就不太清楚了. 一开始实验指导书上是用net send发 ...

  2. 【noi 2.6_9272】偶数个数字3(DP)

    题意:问所有的N位数中,有多少个有偶数个数字3的数. 解法:f[i][j]表示i位数中含数字3的个数模2为j的个数.于是分第i位填3还是不填3讨论. 小tip:要模12345:for循环新定义了一个变 ...

  3. python连接mysql数据库,并进行添加、查找数据

    1.删除MySQL数据表中的记录 DELETE FROM table_name WHERE condition; python操作mysql1数据库 import pymysql # 连接mysql数 ...

  4. Java 窗口 绘制图形 #1

    写在前面: editplus换成eclipse了 Sketchpad要钱,买不起 自己搞(rua) by emeralddarkness 建立了一个平面直角坐标系 两个变元x,y,参数i 实现了以下功 ...

  5. - 迷宫问题 POJ - 3984 bfs记录路径并输出最短路径

    定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, ...

  6. HEXO添加置顶功能

    使用库:参考 http://wangwlj.com/2018/01/09/blog_pin_post/ 目前已经有修改后支持置顶的仓库,可以直接用以下命令安装.(cmd 到博客根目录,nmp运行) $ ...

  7. MDK5生成BIn文件的方法

    配置MDK5 生成bin文件的 第一步:方法打开option for Target 第二步:选择 user 第三步:找到After Build/Rebuild 第四步:勾选run,点击文件选择小图标选 ...

  8. vue2 响应式细节

    data 中的数据是如何处理的? 每一次实例化一个组件,都会调用 initData 然后调用 observe 方法,observe 方法调用了 new Observer(value), 并且返回 __ ...

  9. PHP & LAMP & WAMP

    PHP & LAMP & WAMP https://github.com/xgqfrms/DataStructure/issues/7#issuecomment-430538438 h ...

  10. free online business card generator

    free online business card generator 免费在线名片生成器 https://www.logaster.cn/business-card/ https://www.chu ...