15 LRU缓存

146. LRU 缓存 - 力扣(LeetCode)

这道题采用双向链表加哈希表;

哈希表是为了随机访问,双向链表是为了能够确定位置

这里面注意的是我们需要一个哨兵节点来辅助,需要让哨兵节点的prev.next以及next.next指向自己,即这里是一个双向循环链表,并且我们每次头插节点的时候都是头插在哨兵节点之后

复制代码
class LRUCache {
    //这里put和get想实现O1那么就需要使用哈希表,但是哈希表是没有位置观念的
    //比如我们想删除最久插入的元素,那么只能一个个遍历,而有位置观念的就是数组和链表了
    //但是我们每次插入元素的时候都要放到最前面也就是头插,如果用数组的话,那么元素需要
    //整体移动,所以采用双向链表

    static class Node{
        int key;
        int val;
        Node prev;
        Node next;
        Node(int k ,int v){
            key = k;
            val = v;
        }
    }
    private int capacity;
    private Map<Integer,Node> map = new HashMap<>();
    //设置一个哨兵节点
    private Node head  = new Node(0,0);
 
 //构造初始化
    public LRUCache(int capacity) {
        this.capacity = capacity;
        head.next = head;
        head.prev = head;
    }
    
    public int get(int key) {
        //获取最新节点的值
        Node node = getNode(key);
        return node == null ? -1 : node.val;
        
    }
    
    public void put(int key, int value) {
        Node node = getNode(key);
        if(node != null){
            map.put(key,node);
            node.val = value;
            return;
        } 
        //不存在插入
        Node newNode = new Node(key,value);
        addLeft(newNode);
        map.put(key,newNode);
        if(map.size() > capacity) {
            Node last = head.prev;
            remove(last);
            map.remove(last.key);
        }
        
    }
    private Node getNode(int key){
        Node node = map.get(key);
        if(node == null) return null;
        remove(node);
        addLeft(node);
        return node;
    }
    private void remove(Node node){
        node.next.prev = node.prev;
        node.prev.next = node.next;
    }
    private void addLeft(Node node){
        //插到烧饼节点后面
        node.prev = head;
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
        // node.prev.next = node;
        // node.next.prev = node;
    }
}
相关推荐
nhdh38 分钟前
B+树揭秘:MySQL索引核心原理全解析
数据结构·b树·mysql
海上小飞龙1 小时前
【KMP算法-下篇】同一道题:Java 库函数 2600 微秒,手写 KMP 16 微秒
java·开发语言·算法
青少儿编程课堂1 小时前
后缀自动机解析:本质不同子串与最长重复片段统计
c++·python·算法·bfs·信息学竞赛
朝朝辞暮i1 小时前
C++ 第 12 课:局部变量、作用域、变量生命周期
开发语言·c++·算法
乐迪信息3 小时前
港口船舶逆行怎么管?AI防爆摄像机搭载智能检测算法
大数据·人工智能·深度学习·算法·计算机视觉
Sirens.3 小时前
Java并发锁详解:六类锁策略与 synchronized 底层原理
java·前端·算法
和裕4 小时前
全纸结构重型纸箱能否满足 1 吨以上设备出口熏蒸豁免要求?通关合规性全解析
大数据·运维·网络·人工智能·算法
tangguofeng4 小时前
不带头结点的链队操作集(不含InitFlag)(C语言版)
算法
苏打豆6 小时前
CRISP源码阅读——基于ROS2力矩反馈控制器与速度加速度零空间
c++·线性代数·算法·矩阵·机器人
蛋蛋的就会顺顺的6 小时前
hot100——矩阵
java·数据结构·算法·leetcode·力扣