力扣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;
    }


}
相关推荐
月光船幽幽24 分钟前
呼吸孔设计重塑系统稳定性
python·科技·算法
旖旎夜光40 分钟前
LeetCode 991: 坏了的计算器(贪心算法) —— 题解
数据结构·c++·算法·leetcode·贪心算法
旖旎夜光1 小时前
LeetCode 553:最优除法(贪心算法) —— 题解
数据结构·c++·算法·leetcode·贪心算法
雾喔1 小时前
算法练习7
java·数据结构·算法
过期的秋刀鱼!1 小时前
重点-偏差方差与神经网络
人工智能·深度学习·神经网络·算法·机器学习·过拟合·l2正则化
可编程芯片开发2 小时前
基于模糊PID控制的六步逆变器供电无刷直流电机调速simulink仿真
算法
imperialeast3 小时前
WinAXP音乐播放器8月4日更新
windows·算法·ui
ZhouDevin3 小时前
算法论文/模型微调1——CNN架构做lora微调训练
人工智能·深度学习·算法·架构·cnn
小月土星3 小时前
LeetCode 21. 合并两个有序链表 超详细题解(虚拟头结点 + 逐行代码拆解)
算法
oier_Asad.Chen3 小时前
【OI学习笔记】Floyed-Warshall算法解决传递闭包问题
c++·笔记·学习·算法·图论·最短路·传递闭包