JAVA实现LRU算法

本文介绍了LRU(最近最少使用)算法的工作原理,并详细阐述了如何使用JAVA实现LRU缓存机制,包括LRU的思路分析和代码实现。在实现过程中,结合了HashMap和双向链表,以达到O(1)的时间复杂度完成get和put操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LRU算法

LRU是一种页面置换算法,least recently used(最近最少使用)算法,意思是在发生缺页现象时,需要置换页面的时候,将最近最少使用的页面删除,添加需要的页面进来

LRU举例

下面我们来看看具体的LRU算法是如何工作的,我们假设内存页面有2块,每次访问内存时总会一次性读取一页的数据进来,当页面数量不够时,发生LRU置换:
有以下页面走向:1 2 3 2 4

轮次 1 2 3 4 5
页面1 1 1 2 3 2
页面2 2 3 2 4

每次请求页面的时候,都去寻找最近最不常使用的页面丢弃,将新页面加载进来

LRU题目

运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
实现 LRUCache 类:

  • LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
    int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
  • void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
    进阶:你是否可以在 O(1) 时间复杂度内完成这两种操作?

思路分析

想要实现get和put的操作,想要用Key拿到Value嘛,很容易想到用HashMap来实现,这样子好像get的O(1)操作就完成了,返回一个value,其实不然,因为拿到值之后还需要调整顺序,以便后续让不经常使用的页面删除出去,于是想到用双向链表来存储节点,插入和删除节点都非常简单,但是如何定位这个节点的位置呢?比如我想删除key为2的节点,如果我要在链表中从头遍历一次,那么定位的时间复杂度就是O(n),能实现O(1)的复杂度就是HashMap,于是想到用HashMap来存储Key对应的节点,让key对应一个节点,节点中存储value,找到节点,对节点的前后进行调整,最后让节点挂到尾部表示最近挂载上去的,让删除节点从链表头开始。
get和put,分析如下几种情况:

  • 通过key get到了节点
    • 调整替换的节点到链表尾
  • 通过key 没get到节点
    • 返回-1
  • put插入的时候已有
    • 更新key对应的node中的value值,调整节点到链表尾部
  • put插入的时候没有
    • 容量不够
      • 将新节点挂载到链表尾部,头结点删除
    • 容量充足
      • 新节点直接挂在到链表尾部

代码实现

import java.util.HashMap;

public class LRUCache {
   
   
    class Node {
   
   
        int key;
        int val;
        Node next;
        Node pre;

        public Node(int key, int val, Node next, Node pre) {
   
   
            this.key = key;
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值