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


    }

记录

总结

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

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

相关推荐
前端拾光者2 分钟前
利用D3.js实现数据可视化的简单示例
开发语言·javascript·信息可视化
The_Ticker4 分钟前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
程序猿阿伟4 分钟前
《C++ 实现区块链:区块时间戳的存储与验证机制解析》
开发语言·c++·区块链
傻啦嘿哟22 分钟前
如何使用 Python 开发一个简单的文本数据转换为 Excel 工具
开发语言·python·excel
大数据编程之光26 分钟前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
初九之潜龙勿用26 分钟前
C#校验画布签名图片是否为空白
开发语言·ui·c#·.net
爪哇学长39 分钟前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
Dola_Pan43 分钟前
C语言:数组转换指针的时机
c语言·开发语言·算法
ExiFengs43 分钟前
实际项目Java1.8流处理, Optional常见用法
java·开发语言·spring
paj1234567891 小时前
JDK1.8新增特性
java·开发语言