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);
 */
相关推荐
sanx1818 分钟前
开发体育比分网站,有哪些坑需要注意的
java
gyeolhada1 小时前
2025蓝桥杯JAVA编程题练习Day8
java·数据结构·算法·蓝桥杯
JANYI20181 小时前
一文读懂----Docker 常用命令
java·docker·eureka
黄暄1 小时前
Linux项目部署全攻略:从环境搭建到前后端部署实战
java·linux·运维·服务器·前端·后端·持续部署
艺杯羹1 小时前
数据库连接池技术与 Druid 连接工具类实现
java·数据库·mysql·jdbc
我爱Jack1 小时前
Mybatis操作数据库(2)
java·数据库·mybatis
island13142 小时前
JAVA Web 期末速成
java·开发语言·前端
2401_895610822 小时前
Java 后端基础 Maven
java·开发语言·maven
努力学习的明2 小时前
Spring Bean 生命周期中设计模式的应用与解析
java·spring·设计模式·生命周期
薯条不要番茄酱3 小时前
【SpringBoot】从零开始全面解析SpringMVC (三)
java·spring boot·后端