首页 > 编程语言 >Leedcode【146】. LRU 缓存——Java实现

Leedcode【146】. LRU 缓存——Java实现

时间:2024-06-20 15:28:57浏览次数:23  
标签:146 node Java map Leedcode Node 链表 key 节点

Problem: 146. LRU 缓存

  1. 思路
  2. 解题方法
  3. 复杂度
  4. Code
  5. 效果

思路

使用一个双向链表来维护缓存的访问顺序,最近使用的节点在链表头部,最久未使用的节点在链表尾部。
使用一个哈希表来存储缓存中的键值对,哈希表中的键对应双向链表中的节点。

解题方法

Node类:
表示双向链表的节点,每个节点包含一个键值对以及指向前后节点的指针。

LRUCache类:
包含一个capacity表示缓存容量,map是哈希表,用于O(1)时间复杂度的查找,head和tail是虚拟头尾节点,用于方便地操作双向链表。

构造函数:
初始化缓存容量,创建一个空的哈希表,初始化双向链表的虚拟头尾节点并将它们互相连接。

get方法:
如果键存在于缓存中,则将对应的节点移动到双向链表的头部并返回节点的值。
如果键不存在,返回-1。

put方法:
如果键已经存在,先移除对应的节点。
如果缓存已满,移除双向链表尾部的节点(最久未使用的节点)。
插入新的节点到双向链表的头部。

remove方法:
从双向链表和哈希表中移除节点。

insert方法:
将新节点插入到双向链表的头部并更新哈希表。

复杂度

时间复杂度:

添加时间复杂度, 示例: O(n)O(n)O(n)

空间复杂度:

添加空间复杂度, 示例: O(n)O(n)O(n)

Code

Java

class LRUCache {

    class Node{
        int key, value;
        Node prev;
        Node next;
        Node(int key, int value){
            this.key = key;
            this.value = value;
        }
    }
    private int capacity; //容量
    private Map<Integer, Node> map ;//存放关键字key及结点
    Node head, tail;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        map = new HashMap<>();
        this.head = new Node(0,0);
        this.tail = new Node(0,0);
        head.next = tail;
        tail.prev = head;
    }

    /**
     * 把key存到map里,并更新链表数据,key放在链表头
     * @param key
     * @return
     */
    public int get(int key) {
        if(map.containsKey(key)){
            Node keyNode = map.get(key);
            remove(keyNode);
            insert(keyNode);
            return keyNode.value;
        } else {
            return -1;
        }

    }

    /**
     * 移除结点
     * @param node
     */
    public void remove(Node node){
        map.remove(node.key);
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    public void insert(Node node){
        map.put(node.key, node);
        node.next = head.next;
        node.prev = head;
        head.next.prev = node;
        head.next = node;
    }

    public void put(int key, int value) {
        if(map.containsKey(key)){
            remove(map.get(key));
        }
        if(map.size() >= capacity){
            remove(tail.prev);
        }
        insert(new Node(key, value));
    }
}

/**
 * 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);
 */

效果

image.png

标签:146,node,Java,map,Leedcode,Node,链表,key,节点
From: https://blog.csdn.net/qq_42631788/article/details/139786608

相关文章

  • Leedcode【62】. 不同路径——Java解法(动态规划)
    Problem: 62.不同路径题目思路解题方法复杂度Code效果题目一个机器人位于一个mxn网格的左上角(起始点在下图中标记为“Start”)。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。问总共有多少条不同的路径?示例1:......
  • 在JavaScript中如何获取时间戳?
    在JavaScript中,你可以通过几种方式获取时间戳。最常见的方式是使用Date对象的getTime()方法,这会返回自1970年1月1日00:00:00UTC(世界标准时间)以来的毫秒数。下面是一个简单的例子:javascript//创建一个Date对象,表示当前的时间和日期letnow=newDate();//使用getTime()......
  • 只听过 Python 做爬虫?不瞒你说 Java 也很强
    网络爬虫技术,早在万维网诞生的时候,就已经出现了,今天我们就一起来揭开它神秘的面纱!一、摘要说起网络爬虫,相信大家都不陌生,又俗称网络机器人,指的是程序按照一定的规则,从互联网上抓取网页,然后从中获取有价值的数据,随便在网上搜索一下,排在前面基本都是pyhton教程介绍。的确,pyhto......
  • 学生个人html静态网页制作 基于HTML+CSS+JavaScript+jquery仿苏宁易购官网商城模板
    ......
  • 【java基础】String类的==和equals怎么回事?
    String类是final的,代表不可以被继承了。怎么判断一个类是不是不可变的呢?看里面的成员是不是都用final修饰过了。String里面用byte[]存放字符串的值,而这个value也是final的。就可以认为String是一个不可变的类。Stringobj1=“abc”,那么你再让obj=“bcd”,那么只是让obj指向了一段......
  • JAVA面向对象三大特征————封装
    封装是面向对象的三大特征之一。面向对象的三大特征:封装、继承、多态类=属性+方法,类是对属性和方法的封装。类封装了类的成员。如果在类的外部可以随意访问类的成员,那将属性和方法放到类中就没有意义了。因此Java允许在类中通过访问修饰符控制类成员的访问权限privat......
  • JAVA-面向对象的概念
    面向对象的概念:面向对象编程:OOP(Object-OrientedProgramming)使用类和对象开发程序的基本步骤:对于面向对象编程,主要工作就是编写类。面向对象开发的步骤:l 开发类,类=属性(成员变量)+方法l 通过new关键字创建对象l 使用类中的属性和方法:对象.属性名 对象.方法名()类......
  • 【JavaEE精炼宝库】多线程(7)定时器
    目录一、定时器的概念二、标准库中的定时器三、自己实现一个定时器3.1MyTimerTask实现:3.2MyTimer实现:一、定时器的概念定时器也是软件开发中的⼀个重要组件。类似于一个"闹钟"。达到一个设定的时间之后,就执行某个指定好的代码(可以用来完成线程池里面的非核心线程......
  • Java计算机毕业设计+Vue实习实训管理系统(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在当今社会,实习实训已成为高等教育中不可或缺的一部分,对于学生实践能力和职业素养的提升具有重要意义。然而,传统的实习实训管理方式存在着诸多不便,如......
  • java中的几个关键字
    在Java编程语言中,以下几个关键字扮演了重要角色,它们分别是this,static,super,Object和final。每个关键字都有其特定的用途和行为,理解这些关键字对于编写高效且可靠的Java代码至关重要。1.this关键字this关键字在Java中用来引用当前对象的实例。它有以下几种主要用途:引用......