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);
 */
相关推荐
小年糕是糕手几秒前
【C++】类和对象(二) -- 构造函数、析构函数
java·c语言·开发语言·数据结构·c++·算法·leetcode
豐儀麟阁贵3 分钟前
8.2异常的抛出与捕捉
java·开发语言·python
权泽谦4 分钟前
PHP 版羊了个羊完整开发实战:逻辑解析 + 三消算法 + 全套接口(附源码)
开发语言·php
老华带你飞4 分钟前
社区养老保障|智慧养老|基于springboot+小程序社区养老保障系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·小程序·毕设·社区养老保障
码龄3年 审核中5 分钟前
Linux record 03
java·linux·运维
q***87607 分钟前
springboot下使用druid-spring-boot-starter
java·spring boot·后端
程序员西西8 分钟前
SpringBoot无感刷新Token实战指南
java·开发语言·前端·后端·计算机·程序员
东南门吹雪9 分钟前
Spring的Bean相关
java·spring·bean·aop
q***69779 分钟前
Y20030018基于Java+Springboot+mysql+jsp+layui的家政服务系统的设计与实现 源代码 文档
java·spring boot·mysql
摇滚侠11 分钟前
2025最新 SpringCloud 教程,Nacos-配置中心-数据隔离-动态切换环境,笔记18
java·笔记·spring cloud