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);
 */
相关推荐
行者全栈架构师2 小时前
IDEA 中 Maven 项目的 15 个红色报错快速解决方法
java·后端
令人头秃的代码0_02 小时前
mac(m5)平台编译openjdk
java
JieE21211 小时前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack2019 小时前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树21 小时前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
唐青枫1 天前
Java JDBC 实战指南:从 Connection 到事务和连接池
java
一个做软件开发的牛马1 天前
MyBatis-Plus 从零实战:完整搭建可运行 Demo,BaseMapper 零 SQL、Wrapper 条件构造、分页插件与代码生成器详解
java·后端
用户3721574261351 天前
Java 处理 PDF 图片:提取 PDF 中的图片,并压缩 PDF 图片体积
java
用户3721574261351 天前
Java 打印 Word 文档:从基础打印到高级设置
java
JieE2122 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法