JAVA算法练习题day27

35.LRU缓存

cpp 复制代码
class LRUCache {
    //手写双链表 自己完整独立的写写,好吧,加油。实在写不出再看题解
    //双向链表
    private static class Node{
        int key,value;
        Node prev,next;
        //写初始化方法
        Node(int k, int v){
            key = k;
            value = v;
        }
    }
    private final int capacity;
    private final Node dummy = new Node(0,0);
    private final Map<Integer,Node> key2Node = new HashMap<>();
    public LRUCache(int capacity) {
        this.capacity = capacity;
        //这里还要对dummy进行前后指针的初始化
        dummy.next = dummy;
        dummy.prev = dummy;
    }
    
    //需要返回关键字的值
    public int get(int key) {
        //查询该关键字是否存在对应节点,若存在,将该节点删除而后将该节点放到链表开头,返回关键字的值(也就是节点的值);若不存在则返回-1
        //优化一下,既然get和put都需要去先删除再置顶:写函数getnode,该函数先将节点删除,而后将其置顶
        //再写一个删除节点的函数就好
        Node key2node = getNode(key);
        if(key2node==null) return -1;
        else return key2node.value;
    }
    
    public void put(int key, int value) {
        Node key2node = getNode(key);
        //修改key对应的值为value
        if(key2node!=null){
            key2node.value = value;
        }
        else{
            if(key2Node.size() >= capacity){
                //双向有环链表,找头部就是dummy.next;找尾部就是dummy.prev
                Node lastNode = dummy.prev;
                remove(lastNode);
                //哈希表删除一个
                key2Node.remove(lastNode.key);
                //把新节点放到头部
                Node putnewNode = new Node(key,value);
                push2head(putnewNode);
                //哈希表插入一个
                key2Node.put(key,putnewNode);
            }
            else{
                Node node = new Node(key,value);
                push2head(node);
                key2Node.put(key,node);
            }
        }
    }
    //getNode()
    private Node getNode(int key){
        if(key2Node.containsKey(key)){
            Node node = key2Node.get(key);
            remove(node);
            push2head(node);
            return node;
        }
        else return null;
    }
    //remove()
    private void remove(Node node){
        node.next.prev = node.prev;
        node.prev.next = node.next;
    }
    //push2head
    private void push2head(Node x){
        x.next = dummy.next;
        x.prev=dummy;
        dummy.next.prev=x;
        dummy.next=x;
        //x.prev=dummy;
        //x.next=dummy.next;
        //x.prev.next=x;
        //x.next.prev=x;
    }
}

/**
 * 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);
 */
相关推荐
一木 之林6 分钟前
四、STL容器与数据结构
开发语言·数据结构·c++
QX_hao9 分钟前
【Go】--Cobra-cli的用法
开发语言·后端·golang
程与留15 分钟前
07_QMainWindow 与应用程序框架——菜单栏、工具栏、状态栏
c++·qt
卓怡学长15 分钟前
w180springboot基于Java的悠扬乐器管理
java·spring boot·mysql·spring·maven·intellij-idea
艾醒(AiXing-w)15 分钟前
LangChain 1.0 入门(三):稳定性双核心——重试机制+速率限速器参数详解与实战
开发语言·langchain·php
古法安卓19 分钟前
Android-高版本 LMKD 源码解析:基于 PSI 的内存压力监控与查杀全流程
android·java·android studio
古法安卓24 分钟前
Android-PSI 详解:libpsi 源码解析——116 行代码架起 lmkd 与内核之间的桥
android·java·android studio
用户365330434709429 分钟前
深入理解 Java Unsafe:从底层魔法到被淘汰的命运
java
总有刁民想爱朕ha1 小时前
Python PyQt5图片批量转MP4视频工具:本地离线免费无水印,完整代码
开发语言·python·qt
宸津-代码粉碎机1 小时前
FastUtil+AI多Agent实战:Java AI项目性能终极加速方案
java·服务器·开发语言·python·安全·php