【75.LRU 缓存】

87 阅读1分钟

题目

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

实现 LRUCache 类:

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

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

示例:

输入
["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]

题解

方式一:双端队列 + 哈希表

class LRUCache {

    Deque<Integer> deque = new LinkedList<>(); // 尾部是最久未使用
    Map<Integer, Integer> map = new HashMap<>();
    int size = 0;
    int capacity = 0;

    public LRUCache(int capacity) {
        this.capacity = capacity;
    }

    public int get(int key) {
        if (map.containsKey(key)) {
            // 新访问的元素放到队列头
            deque.remove(key);
            deque.addFirst(key);
            
            return map.get(key);
        }
        return -1;
    }

    public void put(int key, int value) {
        if (map.containsKey(key)) {
            // 新访问的元素放队列头
            deque.remove(key);
            deque.addFirst(key);
            
            map.put(key, value);
        } else if (size == capacity) {
            // 移除队列尾部元素
            int oldKey = deque.peekLast();
            map.remove(oldKey);
            deque.removeLast();
            
            deque.addFirst(key);
            map.put(key, value);
        } else {
            map.put(key, value);
            size++;
            deque.addFirst(key);
        }
    }
}

总结

数据结构:哈希表队列