首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >LeetCode 146. LRU缓存机制 (LRU缓存详解看这一篇就够了)

LeetCode 146. LRU缓存机制 (LRU缓存详解看这一篇就够了)

作者头像
程序员三明治
发布2025-12-18 20:30:09
发布2025-12-18 20:30:09
3090
举报
文章被收录于专栏:码力up码力up
题目

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。

实现 LRUCache 类:

  • LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
  • int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1
  • void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。

函数 getput 必须以 O(1) 的平均时间复杂度运行。

示例:

代码语言:javascript
复制
输入
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]

解释
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1);    // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
lRUCache.get(2);    // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
lRUCache.get(1);    // 返回 -1 (未找到)
lRUCache.get(3);    // 返回 3
lRUCache.get(4);    // 返回 4
思路
题解

自己实现双向链表

代码语言:javascript
复制
class LRUCache {

    private int capacity;
    private HashMap<Integer, Node> map;
    private DoubleList cache;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        map = new HashMap<>();
        cache = new DoubleList();
    }

    public int get(int key) {
        if (map.containsKey(key)) {
            Node node = map.get(key);
            cache.remove(node);
            cache.addLast(node);
            return node.val;
        } else {
            return -1;
        }
    }

    public void put(int key, int value) {
        if (map.containsKey(key)) {
            Node node = map.get(key);
            cache.remove(node);
            Node newNode = new Node(key, value);
            cache.addLast(newNode);
            map.put(key, newNode);
        } else {
            if (map.size() == capacity) {
                Node removeNode = cache.removeFirst();
                map.remove(removeNode.key);
            }
            Node newNode = new Node(key, value);
            cache.addLast(newNode);
            map.put(key, newNode);
        }
    }
}

// 定义双向链表的节点
class Node {
    public int key;
    public int val;
    public Node pre;
    public Node next;
    public Node(int key, int val) {
        this.key = key;
        this.val = val;
    }
}

// 定义双向链表
class DoubleList {
    private Node head;
    private Node tail;

    public DoubleList() {
        this.head = new Node(0, 0);
        this.tail = new Node(0, 0);
        head.next = tail;
        tail.pre = head;
    }

    public void addLast(Node node) {
        tail.pre.next = node;
        node.pre = tail.pre;
        node.next = tail;
        tail.pre = node;
    }

    public void remove(Node node) {
        node.pre.next = node.next;
        node.next.pre = node.pre;
    }

    public Node removeFirst() {
        Node removeNode = head.next;
        removeNode.pre.next = removeNode.next;
        removeNode.next.pre = removeNode.pre;
        return removeNode;
    }
}

/**
 * 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);
 */

使用现成的LinkedHashMap

代码语言:javascript
复制
class LRUCache {

    private int capacity;
    private LinkedHashMap<Integer, Integer> cache = new LinkedHashMap<>();
    public LRUCache(int capacity) {
        this.capacity = capacity;
    }
    
    public int get(int key) {
        Integer val = cache.remove(key);
        if (val != null) {
            cache.put(key, val);
            return val;
        } else {
           return -1;
        }
    }
    
    public void put(int key, int value) {
        Integer val = cache.remove(key);
        //当key在cache中的时候
        if (val != null) {
            cache.put(key, value);
            return;
        }
        // key 不在 cache 中,那么就把 key 插入 cache,插入前判断 cache 是否满了
        if (cache.size() >= capacity) {
            Integer oldestKey = cache.keySet().iterator().next();
            cache.remove(oldestKey);
        }
        cache.put(key, value);
    }
}

/**
 * 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);
 */

如果我的内容对你有帮助,请辛苦动动您的手指为我点赞,评论,收藏。感谢大家!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目
  • 思路
    • 题解
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档