146. LRU 缓存机制 + 哈希表 + 自定义双向链表
146. LRU 缓存机制
LeetCode-146
题目描述
题解分析
java代码
package com.walegarrett.interview;
/**
* @Author WaleGarrett
* @Date 2021/2/19 8:51
*/
import java.util.HashMap;
import java.util.Map;
/**
* 题目描述:运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
* 实现 LRUCache 类:
* LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
* int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
* void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。
* 当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
*
* 进阶:你是否可以在 O(1) 时间复杂度内完成这两种操作?
*/
public class LeetCode_146 {
private DLinkedNode head,tail;//伪头结点和尾结点
private int size,capacity;
private Map<Integer,DLinkedNode> map = new HashMap<>();
public LeetCode_146(int capacity) {
this.size = 0;
this.capacity = capacity;
//创建伪头结点和伪尾结点
head = new DLinkedNode();
tail = new DLinkedNode();
head.next = tail;
tail.pre = head;
}
public int get(int key) {
DLinkedNode node = map.get(key);
if(node == null)
return -1;
//如果key存在,因为这是最新使用的将其移动到头结点
removeToHead(node);
return node.value;
}
public void put(int key, int value) {
DLinkedNode node = map.get(key);
if(node == null){
//如果key不存在,则创建一个新的结点
DLinkedNode newNode = new DLinkedNode(key, value);
map.put(key, newNode);
//添加到链表头部
addToHead(newNode);
++size;
//判断个数是否超出容量
if(size>capacity){
//删除尾部结点
DLinkedNode tail = removeTail();
//删除哈希表中对应的项
map.remove(tail.key);
--size;
}
}else{
//如果key存在,首先更新哈希表中的value
node.value = value;
map.put(key, node);
//该结点为最近访问的结点,添加到头结点
removeToHead(node);
}
}
/**
* 双向链表的自定义实现
*/
class DLinkedNode{
int key,value;
DLinkedNode pre,next;
public DLinkedNode(){}
public DLinkedNode(int _key, int _value){key = _key; value=_value;}
}
/**
* 将新结点放置到头结点
* @param node
*/
private void addToHead(DLinkedNode node){
node.pre = head;
node.next = head.next;
head.next.pre = node;
head.next = node;
}
/**
* 移除当前结点
* @param node
*/
private void removeNode(DLinkedNode node){
node.pre.next = node.next;
node.next.pre = node.pre;
}
/**
* 将当前结点移动到头结点
* @param node
*/
private void removeToHead(DLinkedNode node){
removeNode(node);
addToHead(node);
}
/**
* 删除尾结点
*/
private DLinkedNode removeTail(){
DLinkedNode realTail = tail.pre;
removeNode(realTail);
return realTail;
}
}
复杂度分析
146. LRU 缓存机制 + 哈希表 + 自定义双向链表的更多相关文章
- 力扣 - 146. LRU缓存机制
目录 题目 思路 代码 复杂度分析 题目 146. LRU缓存机制 思路 利用双链表和HashMap来解题 看到链表题目,我们可以使用头尾结点可以更好进行链表操作和边界判断等 还需要使用size变量来 ...
- 【golang必备算法】 Letecode 146. LRU 缓存机制
力扣链接:146. LRU 缓存机制 思路:哈希表 + 双向链表 为什么必须要用双向链表? 因为我们需要删除操作.删除一个节点不光要得到该节点本身的指针,也需要操作其前驱节点的指针,而双向链表才能支持 ...
- Java实现 LeetCode 146 LRU缓存机制
146. LRU缓存机制 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - ...
- 【力扣】146. LRU缓存机制
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果关键字 (key) ...
- [Leetcode]146.LRU缓存机制
Leetcode难题,题目为: 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key ...
- Leetcode 146. LRU 缓存机制
前言 缓存是一种提高数据读取性能的技术,在计算机中cpu和主内存之间读取数据存在差异,CPU和主内存之间有CPU缓存,而且在内存和硬盘有内存缓存.当主存容量远大于CPU缓存,或磁盘容量远大于主存时,哪 ...
- 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 ...
随机推荐
- Codeforces Round #575 (Div. 3) B. Odd Sum Segments 、C Robot Breakout
传送门 B题题意: 给你n个数,让你把这n个数分成k个段(不能随意调动元素位置).你需要保证这k个段里面所有元素加起来的和是一个奇数.问可不可以这样划分成功.如果可以打印YES,之后打印出来是从哪里开 ...
- poj2411 Mondriaan's Dream (用1*2的矩形铺)
Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, af ...
- java实现定时任务解决方案
在线corn表达式 1. 总结常见的实现定时任务的几种方法 thread实现 [原理:通过创建一个线程,让他在while循环里面一直运行,用sleep() 方法让其休眠从而达到定时任务的效果.] Ti ...
- 二进制安装kubernetes(一) 环境准备及etcd组件安装及etcd管理软件etcdkeeper安装
实验环境: 架构图: 主机环境: 操作系统:因docker对内核需要,本次部署操作系统全部采用centos7.6(需要内核3.8以上) VM :2C 2G 50G * 5 PS:因后面实验需要向k8 ...
- 线程池原理讲解——ThreadPoolExecutor
[这是前几天的存货,留着没发表,今天又复习一遍,润化了部分内容,继续干] 说线程池前,先简单回顾一下线程的状态吧: 1.线程状态转换 线程的五种状态,及其转换关系: 2.线程创建方式 三种:两个接口一 ...
- oslab oranges 一个操作系统的实现 实验四 认识保护模式(三):中断异常
实验目的: 理解中断与异常机制的实现机理 对应章节:第三章3.4节,3.5节 实验内容: 1. 理解中断与异常的机制 2. 调试8259A的编程基本例程 3. 调试时钟中断例程 4. 建立IDT,实现 ...
- codeforces 1028C Rectangles【思维】
题目:戳这里 题意:有n个矩阵,求一个点(保证存在)至少在n-1个点内. 解题思路:因为矩阵与坐标轴平行,所以我们画图可以发现如果存在点满足条件,则这些点中一定有一个是矩阵的顶点.我们可以把所有顶点的 ...
- 仿射加密与S-DES加密算法的实现
仿射加密 #include <iostream> #include <cstdio> using namespace std; char letter[30]; char _l ...
- mimikatz+procdump 提取 Windows 明文密码
0x00 原理 获取到内存文件 lsass.exe 进程 (它用于本地安全和登陆策略) 中存储的明文登录密码. 0x01 操作 Windows10/2012 以下的版本:1.上传 procdump 执 ...
- JDK下载安装与卸载详解
JDK下载安装 1. 下载: 推荐版本:JDK 8 (7.8目前广泛应用) 官网地址:https://www.oracle.com/cn/java/technologies/javase/javase ...