146. LRU 缓存

一、题目

二、思路

  • 题目要求 O(1) 的平均时间复杂度运行 -> 使用Map空间换时间 Map<Integer, Node>
  • Map 通过 key 直接找到对应节点 getNode(key) -> Node
  • 记得只要查过该节点之后就应该把该节点放到最前面 pushFront(Node)
  • put 元素后,在map中添加,记得检查是否超过 capacity,超过则删除在map中的元素,以及在链表中的元素 delete(Node)
  • 这里提到的 pushFront(Node) 和 delete(Node) 都是针对双向队列进行位置移动相关的操作,不涉及 Map。

三、代码

java 复制代码
class LRUCache {
    class Node{
        int key,val;
        Node pre, next;

        Node(int key, int val) {
            this.key = key;
            this.val = val;
        }
    }

    Node dummy = new Node(0, 0);
    int capacity;
    Map<Integer, Node> map = new HashMap<>();

	// 初始化双向队列
    public LRUCache(int capacity) {
        dummy.pre = dummy;
        dummy.next = dummy;
        this.capacity = capacity;
    }
    
    
    public int get(int key) {
    	// 从 map 中快速获得 node
        Node node = map.get(key);
        
		// 不存在返回 -1
        if (node == null) {
            return -1;
        }
		// 查询到需要遵循LRU的规则将最近查询的放到队首
        delete(node);
        pushFront(node);
        return node.val;
    }

    public void put(int key, int value) {
        Node node = map.get(key);
        // 已经存在就直接进行更新值,结束 put 方法
        if (node != null) {
            // 更新值
            node.val = value;
            delete(node);
            pushFront(node);
            return ;
        }
        // 不存在就新建一个 node,在双向队列和 map 中同时更新
        node = new Node(key,value);
        pushFront(node);
        map.put(key, node);
		// 更新后检查是否超出容量
		// 超出容量就删除双向队列中的最后一个节点,同时在 map 中删除
        if (map.size() > capacity) {
            Node lastNode = dummy.pre;
            delete(lastNode);
            map.remove(lastNode.key);
        }
    }

	// 将 node 放到双向队列队首
    private void pushFront(Node node) {
        node.next = dummy.next;
        node.pre = dummy;
        dummy.next.pre = node;
        dummy.next = node;
    }
    // 在双向队列中删除 node
    private void delete(Node node) {
        node.pre.next = node.next;
        node.next.pre = node.pre;
    }
}

/**
 * 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);
 */
相关推荐
lee_curry3 小时前
第四章 jvm中的垃圾回收器
java·jvm·垃圾收集器
九转成圣4 小时前
Java 性能优化实战:如何将海量扁平数据高效转化为类目字典树?
java·开发语言·json
直奔標竿5 小时前
Java开发者AI转型第二十七课!Spring AI 个人知识库实战(六)——全栈闭环收官,解锁前端流式渲染终极技巧
java·开发语言·前端·人工智能·后端·spring
金銀銅鐵5 小时前
[java] 编译之后的记录类(Record Classes)长什么样子(上)
java·jvm·后端
野生技术架构师7 小时前
金三银四面试总结篇,汇总 Java 面试突击班后的面试小册
java·面试·职场和发展
小袁拒绝摆烂7 小时前
多表关联大平层转JSON树形结构
java·json
ja哇8 小时前
大厂面试高频八股
java·面试·职场和发展
yoyo_zzm9 小时前
Laravel6.x新特性全解析
java·spring boot·后端
Nick_zcy9 小时前
小说在线阅读网站和小说管理系统 · 功能全解析
java·后端·python·springboot·ruoyi