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);
    }

}
相关推荐
YOU OU1 小时前
Redis基础常识与命令
数据库·redis·缓存
触底反弹3 小时前
🔥 2026 大模型选择指南:别再只看 Benchmark 了,这些维度才是关键!
人工智能·面试
醇氧4 小时前
CountDownLatch / CyclicBarrier / Semaphore 面试高频问答清单
前端·面试·职场和发展
吳所畏惧6 小时前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?
运维·服务器·数据库·redis·缓存·ssh
黄敬峰7 小时前
从零搞懂 useState 与 Fragment:React 函数式组件的基石
面试
谙弆悕博士7 小时前
系统集成项目管理工程师教程(第3版)笔记——第17章:法律法规和标准规范
笔记·职场和发展·学习方法·业界资讯·软考·法律·法规
Y38153266211 小时前
SERP API + Redis 缓存层:4 种方案对比与选型
数据库·redis·缓存
Android研究员12 小时前
Android进阶之事件分发机制深度剖析
android·前端·面试
触底反弹12 小时前
🔥 AI 写代码总翻车?这套实战方法论救了我
人工智能·面试·程序员
风栖柳白杨12 小时前
【面试】AI算法工程师_空白自测版本
人工智能·算法·面试