【d59】【Java】【力扣】146.LRU缓存

思路

代码

复制代码
  class LRUCache {
        //初始化节点:key+value+pre+next
         class Node {
            int key;
            int value;
            Node next;
            Node prev;
            public Node(int key, int value) {this.key = key;this.value = value;}
        }

        //设置链表需要的属性
        //最大容量
        int capacity=0;
        //当前长度
        int size=0;
        //头节点
        Node head;
        //尾节点
        //!!尾节点也要弄使用那种空节点
        Node rear;

        //初始化链表,本质就是对链表的属性 进行一些初始的设置
        public LRUCache(int capacity){
            this.capacity=capacity;
            //使用-1作为区分
            head=new Node(-1, -1);
            rear=new Node(-2, -2);
            rear.prev=head;
            head.next=rear;
        }

        /**
         * 根据key寻找节点,如果存在,返回节点
         * 如果不存在,返回null
         * @param key 需要找的节点的key
         * @return 返回整个节点node
         */
        public Node getNode(int key){
            //判断是否当前节点的key等于 "参数key"
            Node cur=head.next;
            while(cur!=null){
                if (cur.key==key){
                    return cur;
                }
                cur=cur.next;
            }
            //全部遍历后,还没有返回,说明没有这个节点,所以返回null
            return null;
        }

        /**
         * 根据key寻找节点,并返回value,
         * 如果存在这个节点,返回value
         * 如果不存在,返回-1
         * 同时注意:使用这个方法以后,需要把这个节点放到头部
         * @param key
         * @return
         */
        public int get(int key){
            Node node = getNode(key);
            if (node==null){
                return -1;
            }
            //没有返回,说明存在这个节点,则返回节点的value
            //同时做最近使用处理
            hadUsed(node);
            return node.value;
        }

        /**
         * 如果key存在,更改这个value
         * 如果不存在,先头增,再判断是否需要尾删
         * @param key
         * @param value
         */
        public void put(int key, int value){
            Node nodeGet = getNode(key);
            //如果存在
            if (nodeGet!=null){
                nodeGet.value=value;
                                hadUsed(nodeGet);

            }
            //如果不存在
            else {
                Node nodeAdd = new Node(key, value);
                //头增,并size++,,如果这个put是第一次,那么,rear就要向后走
                addFirst(nodeAdd);
                size++;
                //判断是否尾删
                if (size>capacity){
                    removeLast();
                }
            }

        }



        //头增,并判断是不是第一次
        public boolean addFirst(Node node){
            node.next=head.next;
            node.prev=head;
                node.next.prev=node;
            head.next=node;
            return true;
        }

        //尾删:
        public boolean removeLast(){
           Node nodeToRemove=rear.prev;
           removeByNode(nodeToRemove);
           return true;
        }

        //把当前节点,在链表中删除
        private void removeByNode(Node node) {
            //最好 4个操作都写好
            //删除需要 解除这个节点和链表的联系,所以pre和next都要赋空值
            node.prev.next=node.next;
            node.next.prev=node.prev;

            node.next=null;
            node.prev=null;
            }




        public void hadUsed(Node node){
            removeByNode(node);
            addFirst(node);
        }


    }

记录

总结

尾删是一种 特殊的 删除某个元素

所以可以直接调用:删除某个元素

相关推荐
KoiHeng1 分钟前
Java的文件知识与IO操作
java·开发语言
不想写bug呀7 分钟前
买卖股票问题
算法·买卖股票问题
-Try hard-8 分钟前
完全二叉树、非完全二叉树、哈希表的创建与遍历
开发语言·算法·vim·散列表
czlczl2002092510 分钟前
Spring Data Redis
java·redis·spring
知识即是力量ol11 分钟前
在客户端直接上传文件到OSS
java·后端·客户端·阿里云oss·客户端直传
霍理迪15 分钟前
JS作用域与预解析
开发语言·前端·javascript
闻哥18 分钟前
深入理解 Spring @Conditional 注解:原理与实战
java·jvm·后端·python·spring
Traced back19 分钟前
# C# WinForms 数据库清理系统基础知识与避坑指南
开发语言·数据库·c#
煜磊19 分钟前
MD5加盐值-注册与登录
java·开发语言
东东51627 分钟前
校园求职招聘系统设计和实现 springboot +vue
java·vue.js·spring boot·求职招聘·毕设