自学内容网 自学内容网

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


    }

记录

总结

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

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


原文地址:https://blog.csdn.net/m0_74814985/article/details/142732957

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!