首页 > 编程语言 >LRU算法

LRU算法

时间:2023-08-28 18:22:28浏览次数:34  
标签:node Node map int list 算法 LRU key

思路

LRU算法,访问/更新/插入都会将数据置于队尾(假设队头淘汰)。

看3种情况的变化:

  • 插入:简单置于队尾即可。
  • 更新:删除原有节点,新增节点置于队尾。
  • 访问:将原节点提至队尾。

除了插入只需要简单接到链表尾部以外,更新和访问都是可能操作链表中间的,所以自然地就需要引入Map来快速找到对应节点。
并且无论是更新的删除原有节点还是访问的将原节点提至队尾,都需要在链表中间删除节点,所以需要双向链表。

首先实现Node类及DoubleList类,然后按照LRU算法思路实现即可。

代码

原始代码

class LRUCache {

    private int capacity;

    private DoubleList list;

    private Map<Integer, Node> map;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        list = new DoubleList();
        map = new HashMap<>();
    }
    
    public int get(int key) {
        if (!map.containsKey(key)) return -1;
        Node node = map.get(key);
        list.remove(node);
        list.addLast(node);
        return node.val;
    }
    
    public void put(int key, int value) {
         Node node = new Node(key, value);
        // key不存在
        if (!map.containsKey(key)) {
            // 链表大小 == 容量
            if (list.size() == capacity) {
                Node first = list.removeFirst();
                int firstkey = first.key;
                map.remove(first.key);
                int listsize = list.size();
                int mapsize = map.size();
                int a = key;
            }
            map.put(key, node);
            list.addLast(node);
            return;
        } 
        // key存在
        Node oldNode = map.get(key);
        list.remove(oldNode);
        map.put(key, node);
        list.addLast(node);
    }

}

class DoubleList {
    
    private Node head, tail;

    private int size;

    public DoubleList() {
        head = new Node(0, 0);
        tail = new Node(0, 0);
        head.next = tail;
        tail.pre = head;
        size = 0;
    }

    public void addLast(Node node) {
        node.pre = tail.pre;
        node.next = tail;
        tail.pre.next = node;
        tail.pre = node;
        size++;
    }
        
    public void remove(Node node) {
        node.pre.next = node.next;
        node.next.pre = node.pre;
        size--;
    }

    public Node removeFirst() {
        if (head.next == tail)
            return null;
        Node first = head.next;
        remove(first);
        return first;
    }

    public int size() {
        return size;
    }

}

class Node {

    // key为了方便移出双向链表后,再去删除Map中的键值对
    int key;

    int val;

    Node pre;

    Node next;

    public Node(int key, int val) {
        this.key = key;
        this.val = val;
    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

优化代码

标签:node,Node,map,int,list,算法,LRU,key
From: https://www.cnblogs.com/kiper/p/17663114.html

相关文章

  • 空间密度算法DBSCAN和K-means聚类算法有什么区别和联系
    DBSCAN(Density-BasedSpatialClusteringofApplicationswithNoise)和K-means是两种常见的聚类算法,它们有一些区别和联系。区别:原理:K-means是基于距离的划分聚类算法,通过最小化数据点与聚类中心之间的平方误差来进行聚类。DBSCAN是基于密度的聚类算法,通过将密度相连接的数据......
  • 遗传算法解决航路规划问题(MATLAB)
    遗传算法文章部分图片和思路来自司守奎,孙兆亮《数学建模算法与应用》第二版定义:遗传算法是一种基于自然选择原理和自然遗传机制的搜索(寻优)算法,模拟自然界中的声明进化机制,在人工系统中实现特定目标的优化。本质其实就是群体搜索技术,根据适者生存的原则逐代进化,最终得到最优解......
  • [代码随想录]Day29-贪心算法part03
    题目:1005.K次取反后最大化的数组和思路:思路是:先把负数从小到大变成正数(即绝对值由大到小)如果还需要变化(k>0),就变化最小的数在第一步变化的同时顺便记录一个数组和,那么结束之后会有三种情况:k==0;也就是说负数的个数大于等于k,直接返回结果k%2==0;此时全是正整数,......
  • Lnton羚通视频算法算力云平台【PyTorch】教程:torch.nn.ELU
    在PyTorch中,torch.nn.ELU代表指数线性单元(ExponentialLinearUnit),是一种激活函数。ELU函数可以用来增加神经网络的非线性表达能力,使其具备更强的适应性。ELU函数的定义如下:elu(x)=xifx>=0alpha*(exp(x)-1)ifx<0其中,x是输入,alpha是一个正数超参数,控制ELU......
  • 【校招VIP】前端算法考察之排序
    考点介绍:不同的场景中,不同的排序算法执行效率不同。稳定:冒泡、插入、归并不稳定:选择、快速、堆排序、希尔排序一、考点题目1、使用js实现数组的快速排序解答:快速排序使用了冒泡+分治的思路。每轮从数组中取出一个数作为基准;在排序过程中,小于或等于基准数的全部放到基准的左......
  • 【校招VIP】算法考点之堆排
    考点介绍:排序算法属于数据结构和算法的基础内容,并且也是大厂笔试中的高频考点。堆排序是使用一棵树存储序列这个课树只保证跟节点是这棵树中的最小值,但并不保证其他节点是按顺序的。因此他的排序是每次从堆中取得堆顶,取得n次就得到了个数为n的有序序列。一、考点试题1.堆......
  • 监督学习算法中梯度提升决策树(Gradient Boosting Decision Trees)
    梯度提升决策树(GradientBoostingDecisionTrees,简称GBDT)是一种监督学习算法,它是以决策树为基础分类器的集成学习方法。GBDT通过迭代地训练多个弱分类器(决策树),每个弱分类器都在前一个弱分类器的残差上进行训练,从而逐步减小残差,最终将多个弱分类器组合成一个强分类器。具体而言,GB......
  • 【算法】用c#实现计算方法中的经典降幂优化策略,减少计算复杂度
    对于给定的数组[x1,x2,x3,…,xn],计算幂的累积:x1^(x2^(x3^(…^xn))的最后一位(十进制)数字。例如,对于数组[3,4,2],您的代码应该返回1,因为3^(4^2)=3^16=43046721。结果的增长得快得令人难以置信。例如,9^(9^9)有超过3.69亿个数字。你计算的lastDigit必须有效地处理这些数字。我们假设0^0=1,并且空列表......
  • 二分算法
    将两个集合合并询问两个元素是否在一个集合当中基本原理:每个集合用一棵树表示,树根的编号就是整个集合的编号。每个节点储存它的父节点,p[x]表示x的父节点判断树根(属于那个集合)if(p[x]==x)求x的集合编号:while(p[x]!=x)x=p[x];合并两个集合:px是x的集合编号,py是y的......
  • Bresenham画直线算法(待完成)
    目录问题描述Bresenham算法Bresenham算法是图形学非常经典的光栅线生成算法,可用于显示直线、圆以及其他曲线。这里通过算法画直线过程,了解其工作原理。问题描述已知线段2端点\((x_0,y_0)(x_e,y_e)\),屏幕上画出该直线段。由于屏幕是通过像素点显示的,只能通过像素点所在的整......