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


}
相关推荐
源码之家2 小时前
大数据毕业设计汽车推荐系统 Django框架 可视化 协同过滤算法 数据分析 大数据 机器学习(建议收藏)✅
大数据·python·算法·django·汽车·课程设计·美食
Boop_wu2 小时前
[Java 算法] 哈希表(1)
leetcode·哈希算法·散列表
nianniannnn2 小时前
力扣 3.无重复字符的最长子串
c++·算法·leetcode
IT大师兄吖2 小时前
flux-2-Klein-BFS-换头换脸工作流 懒人整合包
算法·宽度优先
波哥学开发2 小时前
深入解析 BEV 图像色彩调整与伪彩色映射:从直方图统计到着色器实现
算法·图形学
鬼蛟2 小时前
Redis
数据库·redis·缓存
西西弟2 小时前
最短路径之Floyd算法(数据结构)
数据结构·算法
小O的算法实验室2 小时前
2026年SEVC,直觉模糊不确定环境下求解绿色多物品固定费用五维运输问题的多目标进化算法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
海海不瞌睡(捏捏王子)3 小时前
Unity A*寻路算法
算法·unity