LeetCode 刷题【146. LRU 缓存】

146. LRU 缓存

自己做

解:集合哈希

java 复制代码
class LRUCache {
    Map<Integer, Integer> data;
    Map<Integer, Integer> key_time; //根据key查询时间
    Map<Integer, Integer> time_key; //根据时间查询key
    int now_time = 0;               //当前时间
    int len = 0;                    //最大数据存放量

    public LRUCache(int capacity) {
        data = new HashMap();
        key_time = new HashMap();
        time_key = new TreeMap();
        len = capacity;
    }
    
    public int get(int key) {
        if(data.containsKey(key)){                  //找到数据
            time_key.remove(key_time.get(key));     //更新访问时间
            time_key.put(now_time, key);
            key_time.put(key, now_time++);      

            //返回数据
            return data.get(key);
        }

        return -1;
        
    }
    
    public void put(int key, int value) {
        if(data.containsKey(key)){                  //判断数据原先是否存在
            data.put(key, value);                   //更新数据
            time_key.remove(key_time.get(key));     //更新原本的时间
            time_key.put(now_time, key);
            key_time.put(key, now_time++);
        }
        else{                                       //正常添加
            if(data.size() == len){                 //队满了
                Map.Entry<Integer, Integer> firstEntry = time_key.entrySet().iterator().next();     //淘汰最早的(时间最前的)
                int k = firstEntry.getValue();

                time_key.remove(key_time.get(k));
                key_time.remove(k);
                data.remove(k);
            }

            data.put(key, value);
            key_time.put(key, now_time);
            time_key.put(now_time++, key);
        }

    }
}

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

看题解

官方题解:双向链表+哈希

java 复制代码
public class LRUCache {
    class DLinkedNode {
        int key;
        int value;
        DLinkedNode prev;
        DLinkedNode next;
        public DLinkedNode() {}
        public DLinkedNode(int _key, int _value) {key = _key; value = _value;}
    }

    private Map<Integer, DLinkedNode> cache = new HashMap<Integer, DLinkedNode>();
    private int size;
    private int capacity;
    private DLinkedNode head, tail;

    public LRUCache(int capacity) {
        this.size = 0;
        this.capacity = capacity;
        // 使用伪头部和伪尾部节点
        head = new DLinkedNode();
        tail = new DLinkedNode();
        head.next = tail;
        tail.prev = head;
    }

    public int get(int key) {
        DLinkedNode node = cache.get(key);
        if (node == null) {
            return -1;
        }
        // 如果 key 存在,先通过哈希表定位,再移到头部
        moveToHead(node);
        return node.value;
    }

    public void put(int key, int value) {
        DLinkedNode node = cache.get(key);
        if (node == null) {
            // 如果 key 不存在,创建一个新的节点
            DLinkedNode newNode = new DLinkedNode(key, value);
            // 添加进哈希表
            cache.put(key, newNode);
            // 添加至双向链表的头部
            addToHead(newNode);
            ++size;
            if (size > capacity) {
                // 如果超出容量,删除双向链表的尾部节点
                DLinkedNode tail = removeTail();
                // 删除哈希表中对应的项
                cache.remove(tail.key);
                --size;
            }
        }
        else {
            // 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部
            node.value = value;
            moveToHead(node);
        }
    }

    private void addToHead(DLinkedNode node) {
        node.prev = head;
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
    }

    private void removeNode(DLinkedNode node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    private void moveToHead(DLinkedNode node) {
        removeNode(node);
        addToHead(node);
    }

    private DLinkedNode removeTail() {
        DLinkedNode res = tail.prev;
        removeNode(res);
        return res;
    }
}

作者:力扣官方题解
链接:https://leetcode.cn/problems/lru-cache/solutions/259678/lruhuan-cun-ji-zhi-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
相关推荐
春日见1 小时前
算法与数据结构----哈希表
数据结构·人工智能·算法·机器学习·自动驾驶·哈希算法·散列表
tachibana22 小时前
hot100 数组中的第K个最大元素(215)
java·数据结构·算法·leetcode
晚笙coding4 小时前
LeetCode 98:验证二叉搜索树 —— 从局部判断到全局范围约束的递归思想
算法·leetcode·职场和发展
兰令水5 小时前
hot100【acm版】【2026.7.21打卡-java版本】
java·开发语言·算法·leetcode·面试
咏方舟【长江支流】6 小时前
【开源】跨语言·跨平台·跨数据库(6) ——一种ORM缓存的接口实现和容错处理
数据库·缓存·开源·咏方舟-长江支流·用宝框架
退休倒计时6 小时前
【每日一题】LeetCode 131. 分割回文串 TypeScript
算法·leetcode·typescript
爬也要爬着前进19 小时前
redis主从搭建
数据库·redis·缓存
旖-旎1 天前
LeetCode 279:完全平方数(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题
良木林1 天前
滑动窗口 - LeetCode hot 100
javascript·算法·leetcode·双指针·滑动窗口
晚笙coding1 天前
LeetCode 108:将有序数组转换为二叉搜索树 —— 从数组到平衡二叉树的递归构造
数据结构·算法·leetcode