力扣HOT100 Q146LRU缓存

需要创建一个map和一个双向链表

map中key为输入的key,value为一个Node结点

java 复制代码
import java.util.HashMap;
import java.util.Map;

class LRUCache {

    /**
     * 双向链表节点
     */
    class Node {
        int key, value;
        // 前驱和后继
        Node prev, next;

        /**
         * 全参构造
         * @param k
         * @param v
         */
        public Node(int k, int v) {
            key = k;
            value = v;
        }

        /**
         * 空参构造
         */
        public Node() {

        }
    }

    // 缓存
    private Map<Integer, Node> cache = new HashMap<>();

    // 当前缓存大小
    private int size;

    // 总缓存大小
    private int capacity;

    // 双向链表的头尾哨兵节点,不存储数据
    private Node head, tail;

    /**
     * 初始化双向链表
     * @param capacity
     */
    public LRUCache(int capacity) {
        this.capacity = capacity;
        head = new Node();
        tail = new Node();
        head.next = tail;
        tail.prev = head;
    }

    /**
     * 获得key
     * @param key
     * @return
     */
    public int get(int key) {
        Node node = cache.get(key);
        if (node == null) {
            return -1;
        }
        // 如果key存在,需要移动双向链表
        moveToHead(node);
        return node.value;
    }

    /**
     * 添加结点
     * @param key
     * @param value
     */
    public void put(int key, int value) {
        // 先判断是否存在结点
        Node node = cache.get(key);
        // 如果不存在,需要创建节点
        if (node == null) {
            // 创建结点
            Node newNode = new Node(key, value);
            // 加入哈希表
            cache.put(key, newNode);
            // 加入双向链表
            addToHead(newNode);
            // 当前容量 +1
            size++;
            // 判断是否超出容量
            if (size > capacity) {
                // 删除双向链表的尾节点
                Node lastNode = removeTail();
                // 删除哈希表中的key-value
                cache.remove(lastNode.key);
                size--;
            }
        } else {
            // 没有超出容量
            // 修改value
            node.value = value;
            // 移动到头结点
            moveToHead(node);
        }
    }

    /**
     * 移除尾节点
     * @return 删除的节点
     */
    private Node removeTail() {
        Node prev = tail.prev;
        moveToList(prev);
        return prev;
    }

    /**
     * 移除结点并且添加到头结点
     * @param node
     */
    private void moveToHead(Node node) {
        moveToList(node);
        addToHead(node);
    }


    /**
     * 添加到链表头部
     * @param node
     */
    private void addToHead(Node node) {
        node.next = head.next;
        node.prev = head;
        head.next.prev = node;
        head.next = node;
    }

    /**
     * 把当前结点移除链表
     * @param node
     */
    private void moveToList(Node node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }


}
相关推荐
:-)7 小时前
算法-归并排序
java·开发语言·数据结构·算法·排序算法
白露与泡影8 小时前
Redis 缓存实战:雪崩、穿透、击穿一次讲透
数据库·redis·缓存
Jerry11 小时前
LeetCode 101. 对称二叉树
算法
可编程芯片开发12 小时前
基于MPPT最大功率跟踪的离网光伏发电系统Simulink建模与仿真
算法
AI科技星12 小时前
线性算子不是空间映射函数,是全域双螺旋场之间拉伸、旋转、耦合、坍缩的跨空间标准化变换载体《全域数学vs传统数学:人类文明进阶200讲》第80讲
线性代数·算法·矩阵·数据挖掘·回归·乖乖数学·全域数学
米罗篮12 小时前
矩阵快速幂 (Exponentiation By Squaring Applied To Matrices)
c++·线性代数·算法·矩阵
dream_home840712 小时前
图像算法模型NPU适配与算法服务实战指南
人工智能·python·算法·npu 图像服务
大鱼>13 小时前
多宠物家庭智能管理平台:云端架构与多设备协同实战
python·算法·iot·宠物
snow@li13 小时前
Redis:数据库语法速查表 / 全景梳理
数据库·redis·缓存
To_OC13 小时前
LC 22 括号生成:刷完这道题,我终于搞懂回溯剪枝了
javascript·算法·leetcode