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


}
相关推荐
v_34836087626 小时前
Android native端 堆栈打印
android·算法
residual_fan6 小时前
【学术论文】航空发动机故障诊断智能体:基于持续对比强化学习的动态优化方法
人工智能·算法·数据挖掘·数据分析
GreenTea6 小时前
OpenAI Agents API 上手实测:一次调用把整个 agent loop 甩给 OpenAI
前端·后端·算法
wdfk_prog6 小时前
ROS教程:01 搭建 ROS1 Noetic Docker 开发环境
运维·缓存·docker·容器·ros
深圳满意度咨询7 小时前
医院满意度数字化测评系统:从数据采集到智能决策的技术实践
算法
wdfk_prog7 小时前
ros教程02:创建 catkin Workspace、Package 与第一个 ROS1 C++ Node
运维·缓存·docker·容器·ros
xiangyun618 小时前
【408数据结构 08】队列:循环队列判空判满,408年年考,一次讲清
c语言·开发语言·数据结构·c++·算法
xiangyun618 小时前
【408数据结构 06】双链表、循环链表、静态链表
c语言·开发语言·数据结构·c++·算法
302wanger10 小时前
推荐下我的两个AI信息源
算法
索尔~古德曼10 小时前
CF——错题的集合
算法