LRU缓存

这是一个很经典的面试题

146. LRU 缓存 - 力扣(LeetCode)

请你设计并实现一个满足 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) 的平均时间复杂度运行。

这是一个设计数据结构的题

如果没有第三个要求,HashMap+List就可以是实现,

可是还需要O(1)的复杂度

可以使用双向链表加Hash表去解决,为什么要用hash表了,因为要快速判断这个key存在于这个链表,

解法一:自定义双向链表

java 复制代码
class LRUCache3{
    private static class Node{
        int key,value;
        Node pre,next;
        public Node(int key,int value){
            this.key=key;
            this.value=value;
        }
    }
    private int capacity;
    private Node head=new Node(0,0);
    private HashMap<Integer,Node> map=new HashMap<>();

    public LRUCache3(int capacity) {
        this.capacity=capacity;
        head.pre=head;
        head.next=head;
    }
    public int get(int key){
         if(!map.containsKey(key)){
             return -1;
         }
         Node k=map.get(key);
         remove(k);
         add(k);
         return k.value;
    }
    public void put(int key,int value){
             if(map.containsKey(key)){
                 Node node = map.get(key);
                 node.value=value;
                 remove(node);
                 add(node);
                 return ;
             }
             if(map.size()==capacity){
                 Node last = head.pre;
                 remove(last);
                 map.remove(last.key);
             }
             add(new Node(key,value));
    }
    private void remove(Node k){
     k.pre.next=k.next;
     k.next.pre=k.pre;
    }
    private void add(Node k){
        k.pre=head;
        k.next=head.next;
        k.pre.next=k;
        k.next.pre=k;
    }
}

解法二:使用LinkedHashmap 本身自带双向链表

LinkedHashMap

java 复制代码
LinkedHashMap<Integer,String> linkedHashMap = new LinkedHashMap<>(16,0.75f,true);

boolean accessOrder决定按什么排序,为true则为按访问顺序,为false则为插入顺序

java 复制代码
    public LinkedHashMap(int initialCapacity,
                         float loadFactor,
                         boolean accessOrder) {
        super(initialCapacity, loadFactor);
        this.accessOrder = accessOrder;
    }

如果按照插入顺序写会固定不变,所以应该用true

java 复制代码
class  LRUCache2{
    // LinkedHashMap 最早是在上面, 最近使用的在下面。
    private int capacity;
    private LinkedHashMap<Integer, Integer> map;
    public LRUCache2(int capacity) {
        this.capacity = capacity;
        map = new LinkedHashMap<>();
    }

    public int get(int key) {
        Integer remove = map.remove(key);
        if(remove !=null ){
            map.put(key,remove);
            return remove;
        }
        return -1;
    }

    public void put(int key, int value) {
         if(map.remove(key)!=null){
             map.put(key,value);
             return ;
         }
         if(map.size()==capacity){
             map.remove(map.keySet().iterator().next());
         }
         map.put(key,value);
    }
}

第三种 继承LinkedHashMap

java 复制代码
class  LRUCache extends LinkedHashMap<Integer, Integer>{
    private static final float DEFAULT_LOAD_FACTOR = 0.75f;
    private final int capacity;
    public LRUCache(int capacity) {
        super(capacity, DEFAULT_LOAD_FACTOR, true);
        this.capacity = capacity;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
        return size() > capacity;
    }

    public int get(int key) {
      return super.getOrDefault(key, -1);
    }

}
相关推荐
码匠许师傅7 分钟前
【C++ 面试真题】30. 聊聊 C++ 的互斥锁与读写锁
java·c++·面试
Heo2 小时前
怎么保证缓存和数据库一致性?
前端·后端·面试
晓晓_za8986682 小时前
Geo 优化服务 CI/CD 流水线搭建:源码自动构建、测试与灰度发布
运维·服务器·tcp/ip·spring·缓存·ci/cd
众人皆醒我独醉3 小时前
调和循环:kubectl apply 之后发生了什么
面试·llm·gpu
众人皆醒我独醉3 小时前
从 Spec 到资源:Predictor/Transformer/Explainer 如何变成 Deployment
面试·llm·gpu
面试鸭4 小时前
Codex 跑进法务部,周活居然暴涨了 108 倍???
后端·面试·求职
程序员爱钓鱼6 小时前
Rust const泛型详解:让常量也成为泛型参数
后端·面试·rust
nvd117 小时前
LiteLLM 与 Redis 响应缓存机制:从精确哈希匹配到模型底层 KV-Cache 边界
redis·缓存·哈希算法
黄敬峰7 小时前
一文搞懂 Next.js + AI 全栈开发:为什么它是 2026 年最强的 AI 全栈框架
面试
吴声子夜歌8 小时前
Java面试——数据结构(一)
java·数据结构·面试