力扣 - 146. LRU缓存机制
题目
思路
- 利用双链表和HashMap来解题
- 看到链表题目,我们可以使用头尾结点可以更好进行链表操作和边界判断等
- 还需要使用size变量来存储双链表的当前长度
- 调用get,如果存在的话,我们可以调用将在双链表中的结点通过修改指针移动到第一个;如果调用put,我们先判断是否存在该结点,如果不存在,可直接将链接插入即可,同时size++,如果存在的话,先删除原来的结点,再将新结点push到头部即可
代码
class LRUCache {
class Node {
int key;
int val;
Node pre;
Node next;
public Node() {}
public Node(int key, int val) {
this.key = key;
this.val = val;
}
}
// 哈希表中的node和双链表的node是同一个结点
private HashMap<Integer, Node> cache;
private Node dummyHead;
private Node dummyTail;
private int size;
private int capacity;
public LRUCache(int capacity) {
cache = new HashMap<>();
dummyHead = new Node();
dummyTail = new Node();
dummyHead.next = dummyTail;
dummyTail.pre = dummyHead;
this.capacity = capacity;
this.size = 0;
}
public int get(int key) {
// 先获取看看结点存不存在
Node node = cache.get(key);
// 如果存在的话,将当前访问的结点移动到链表头,并且返回值
if (node != null) {
moveToHead(node);
return node.val;
}
// 不存在的话就返回-1
return -1;
}
public void put(int key, int value) {
// 也是先看看结点是否存在
Node node = cache.get(key);
// 如果存在,那么要做的操作就是将结点移动到链表头,然后更新结点值即可
if (node != null) {
node.val = value;
moveToHead(node);
} else {
// 如果不存在的话我们就要创建新结点插入
Node newNode = new Node(key, value);
// 先添加到哈希表中
cache.put(key, newNode);
// 再添加到链表中
addToHead(newNode);
// 并且长度+1
size++;
// 因为我们设定最大容量,我们还要判断新put的结点后,容量是否超过了capacity,超过了话,删除最后一个结点,并且长度-1
if (size > capacity) {
Node tail = removeTail();
cache.remove(tail.key);
size--;
}
}
}
/**
* 将node移动到最前面
*/
private void moveToHead(Node node) {
if (size > 0 && size <= capacity) {
remove(node);
addToHead(node);
}
}
/**
* 删除node结点
*/
private void remove(Node node) {
if (size > 0) {
node.pre.next = node.next;
node.next.pre = node.pre;
}
}
/**
* 删除最后一个结点
*/
private Node removeTail() {
if (size > 0) {
Node node = dummyTail.pre;
remove(node);
return node;
}
return null;
}
/**
* 添加新结点到第一位去
*/
private void addToHead(Node node) {
node.next = dummyHead.next;
dummyHead.next = node;
node.next.pre = node;
node.pre = dummyHead;
}
}
复杂度分析
- 时间复杂度:\(O(1)\)
- 空间复杂度:\(O(N)\),其中 N 为初始化的 capacity 容量
力扣 - 146. LRU缓存机制的更多相关文章
- 【golang必备算法】 Letecode 146. LRU 缓存机制
力扣链接:146. LRU 缓存机制 思路:哈希表 + 双向链表 为什么必须要用双向链表? 因为我们需要删除操作.删除一个节点不光要得到该节点本身的指针,也需要操作其前驱节点的指针,而双向链表才能支持 ...
- Java实现 LeetCode 146 LRU缓存机制
146. LRU缓存机制 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - ...
- 146. LRU 缓存机制 + 哈希表 + 自定义双向链表
146. LRU 缓存机制 LeetCode-146 题目描述 题解分析 java代码 package com.walegarrett.interview; /** * @Author WaleGar ...
- 【力扣】146. LRU缓存机制
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果关键字 (key) ...
- [Leetcode]146.LRU缓存机制
Leetcode难题,题目为: 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key ...
- 146. LRU缓存机制
题目描述 运用你所掌握的数据结构,设计和实现一个LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果密钥 (key ...
- leetcode:146. LRU缓存机制
题目描述: 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果密钥 ( ...
- LeetCode 146. LRU缓存机制(LRU Cache)
题目描述 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果密钥 (k ...
- Leetcode 146. LRU 缓存机制
前言 缓存是一种提高数据读取性能的技术,在计算机中cpu和主内存之间读取数据存在差异,CPU和主内存之间有CPU缓存,而且在内存和硬盘有内存缓存.当主存容量远大于CPU缓存,或磁盘容量远大于主存时,哪 ...
随机推荐
- iPhone手机越狱-逆向砸壳-代码注入
iPhone手机越狱 逆向砸壳 代码注入 工具下载 操作越狱 安装待逆向应用(app) 使用OpenSSH连接手机 找到应用二进制文件地址 找到应用document沙盒地址 拷贝砸壳工具(dumpde ...
- JVM初步入门(很初级,建议只做大致了解用)
jvm初步入门 本博客中的所有内容都是来自b站狂神说视频教程,如有侵权联系我删除. 下面是视频链接:b站狂神说 关于jvm的几个小问题 1. jvm的位置: jvm是一个运行在操作系统上的用c语言编写 ...
- 从实体框架核心开始:构建一个ASP。NET Core应用程序与Web API和代码优先开发
下载StudentApplication.Web.zip - 599.5 KB 下载StudentApplication.API.zip - 11.5 KB 介绍 在上一篇文章中,我们了解了实体框架的 ...
- 翻了翻element-ui源码,发现一个很实用的指令clickoutside
前言 指令(directive)在 vue 开发中是一项很实用的功能,指令可以绑定到某一元素或组件,使功能的颗粒度更精细.今天在翻 element-ui 的源码时,发现一个还挺实用的工具指令,跟大伙分 ...
- 用composer安装captcha_src()不成功
1,要么就是TP的框架配置有问题建议重新下载 2,要么就是下载captcha_src的语句有问题 正确的语句 composer require topthink/think-captcha 1.* ...
- 《流畅的Python》第二部分 数据结构 【序列构成的数组】【字典和集合】【文本和字节序列】
第二部分 数据结构 第2章 序列构成的数组 内置序列类型 序列类型 序列 特点 容器序列 list.tuple.collections.deque - 能存放不同类型的数据:- 存放的是任意类型的对象 ...
- python进程开启的两种方式
一.进程 1.1.方式一 from multiprocessing import Process import time #方式一 def task(name): print(f"my na ...
- SpringBoot整合Mybatis 编译失败:找不到符号 程序包不存在
问题描述:jpa不好用,转用mybatis,配置多数据源 但是配置后无法编译mvn clean install dao层这些报错,找不到entity的包 问题解决:罪魁祸首:热部署的部分 ...
- MeteoInfoLab脚本示例:计算水平螺旋度
尝试了用MeteoInfoLab编写计算水平螺旋度的脚本,结果未经验证.脚本程序: print 'Open data files...' f_uwnd = addfile('D:/Temp/nc/uw ...
- MeteoInfoLab脚本示例:读取远程文件
利用Unidata netCDF Java库对远程文件的读取能力(OpenDAP, ADDE, THREDDS等),可以读取远程文件并绘图.脚本程序: fn = 'http://monsoondata ...