146. LRU 缓存

[复制链接]
发表于 2025-8-15 10:03:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
一、题目


二、思路


  • 题目要求 O(1) 的平均时间复杂度运行 -> 使用Map空间换时间 Map<Integer, Node>
  • Map 通过 key 直接找到对应节点 getNode(key) -> Node
  • 记得只要查过该节点之后就应该把该节点放到最前面 pushFront(Node)
  • put 元素后,在map中添加,记得检查是否凌驾 capacity,凌驾则删除在map中的元素,以及在链表中的元素 delete(Node)
  • 这里提到的 pushFront(Node) 和 delete(Node) 都是针对双向队列进行位置移动相关的操作,不涉及 Map。
三、代码
  1. class LRUCache {
  2.     class Node{
  3.         int key,val;
  4.         Node pre, next;
  5.         Node(int key, int val) {
  6.             this.key = key;
  7.             this.val = val;
  8.         }
  9.     }
  10.     Node dummy = new Node(0, 0);
  11.     int capacity;
  12.     Map<Integer, Node> map = new HashMap<>();
  13.         // 初始化双向队列
  14.     public LRUCache(int capacity) {
  15.         dummy.pre = dummy;
  16.         dummy.next = dummy;
  17.         this.capacity = capacity;
  18.     }
  19.    
  20.    
  21.     public int get(int key) {
  22.             // 从 map 中快速获得 node
  23.         Node node = map.get(key);
  24.         
  25.                 // 不存在返回 -1
  26.         if (node == null) {
  27.             return -1;
  28.         }
  29.                 // 查询到需要遵循LRU的规则将最近查询的放到队首
  30.         delete(node);
  31.         pushFront(node);
  32.         return node.val;
  33.     }
  34.     public void put(int key, int value) {
  35.         Node node = map.get(key);
  36.         // 已经存在就直接进行更新值,结束 put 方法
  37.         if (node != null) {
  38.             // 更新值
  39.             node.val = value;
  40.             delete(node);
  41.             pushFront(node);
  42.             return ;
  43.         }
  44.         // 不存在就新建一个 node,在双向队列和 map 中同时更新
  45.         node = new Node(key,value);
  46.         pushFront(node);
  47.         map.put(key, node);
  48.                 // 更新后检查是否超出容量
  49.                 // 超出容量就删除双向队列中的最后一个节点,同时在 map 中删除
  50.         if (map.size() > capacity) {
  51.             Node lastNode = dummy.pre;
  52.             delete(lastNode);
  53.             map.remove(lastNode.key);
  54.         }
  55.     }
  56.         // 将 node 放到双向队列队首
  57.     private void pushFront(Node node) {
  58.         node.next = dummy.next;
  59.         node.pre = dummy;
  60.         dummy.next.pre = node;
  61.         dummy.next = node;
  62.     }
  63.     // 在双向队列中删除 node
  64.     private void delete(Node node) {
  65.         node.pre.next = node.next;
  66.         node.next.pre = node.pre;
  67.     }
  68. }
  69. /**
  70. * Your LRUCache object will be instantiated and called as such:
  71. * LRUCache obj = new LRUCache(capacity);
  72. * int param_1 = obj.get(key);
  73. * obj.put(key,value);
  74. */
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表