数据结构与算法之链表: LeetCode 146. LRU 缓存 (Ts版)

server/2025/1/15 4:12:54/

LRU 缓存

  • https://leetcode.cn/problems/lru-cache/description/

描述

  • 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构
    实现 LRUCache 类:
    • LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
    • int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1
    • void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value
    • 如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字
  • 函数 get 和 put 必须以 O(1) 的平均时间复杂度运行

示例

输入
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]

解释
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1); // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
lRUCache.get(2); // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
lRUCache.get(1); // 返回 -1 (未找到)
lRUCache.get(3); // 返回 3
lRUCache.get(4); // 返回 4

提示

  • 1 <= capacity <= 3000
  • 0 <= key <= 10000
  • 0 <= value <= 1 0 5 10^5 105
  • 最多调用 2 * 1 0 5 10^5 105 次 get 和 put

Typescript 版算法实现


1 ) 方案1: 基于Map

class LRUCache {public cache: Map<number, any>public max: numberconstructor(capacity: number) {this.cache = new Map()this.max = capacity}get(key: number): number {if (!this.cache.has(key)) return -1const tmp = this.cache.get(key)this.cache.delete(key)this.cache.set(key, tmp)return tmp}put(key: number, value: number): void {if(this.cache.has(key)) {this.cache.delete(key)} else if(this.cache.size >= this.max) {// 新增时的淘汰机制this.cache.delete(this.cache.keys().next().value)}this.cache.set(key, value)}
}/*** Your LRUCache object will be instantiated and called as such:* var obj = new LRUCache(capacity)* var param_1 = obj.get(key)* obj.put(key,value)*/

2 ) 方案2: 哈希表 + 双向链表

class DLinkedNode {key: number;value: number;prev: DLinkedNode | null;next: DLinkedNode | null;constructor(key: number = 0, value: number = 0) {this.key = key;this.value = value;this.prev = null;this.next = null;}
}class LRUCache {private size: number;private capacity: number;private cache: Map<number, DLinkedNode>;private head: DLinkedNode;private tail: DLinkedNode;constructor(capacity: number) {this.size = 0;this.capacity = capacity;this.cache = new Map();this.head = new DLinkedNode();this.tail = new DLinkedNode();this.head.next = this.tail;this.tail.prev = this.head;}private addToHead(node: DLinkedNode): void {node.prev = this.head;node.next = this.head.next;this.head.next!.prev = node;this.head.next = node;}private removeNode(node: DLinkedNode): void {node.prev!.next = node.next;node.next!.prev = node.prev;}private moveToHead(node: DLinkedNode): void {this.removeNode(node);this.addToHead(node);}private removeTail(): DLinkedNode {const node = this.tail.prev!;this.removeNode(node);return node;}public get(key: number): number {if (!this.cache.has(key)) {return -1;}const node = this.cache.get(key)!;this.moveToHead(node);return node.value;}public put(key: number, value: number): void {if (!this.cache.has(key)) {const newNode = new DLinkedNode(key, value);this.cache.set(key, newNode);this.addToHead(newNode);this.size++;if (this.size > this.capacity) {const removedNode = this.removeTail();this.cache.delete(removedNode.key);this.size--;}} else {const node = this.cache.get(key)!;node.value = value;this.moveToHead(node);}}
}/*** Your LRUCache object will be instantiated and called as such:* var obj = new LRUCache(capacity)* var param_1 = obj.get(key)* obj.put(key,value)*/

http://www.ppmy.cn/server/158457.html

相关文章

Oracle Dataguard(主库为双节点集群)配置详解(5):将主库复制到备库并启动同步

Oracle Dataguard&#xff08;主库为双节点集群&#xff09;配置详解&#xff08;5&#xff09;&#xff1a;将主库复制到备库并启动同步 目录 Oracle Dataguard&#xff08;主库为双节点集群&#xff09;配置详解&#xff08;5&#xff09;&#xff1a;将主库复制到备库并启动…

深入理解 Java 设计模式之策略模式

一、引言 在 Java 编程的世界里&#xff0c;设计模式就如同建筑师手中的蓝图&#xff0c;能够帮助我们构建出更加健壮、灵活且易于维护的代码结构。而策略模式作为一种经典的行为型设计模式&#xff0c;在诸多实际开发场景中都发挥着至关重要的作用。它能够让算法的定义与使用…

wsl2上mysql出现ip端口冲突问题

现象出现于win11系统wsl2平台跑ubuntu&#xff0c;在win11 22h2之后提供固化wsl ip地址的功能&#xff0c;具体可以百度&#xff0c;大概是在C:/用户/用户名文件夹下新建.wslconfig文件&#xff0c;其中添加固化IP地址的参数。 固化完毕后&#xff0c;wsl将不再使用虚拟ip&…

Eureka缓存机制

一、Eureka的CAP特性 Eureka是一个AP系统&#xff0c;它优先保证可用性&#xff08;A&#xff09;和分区容错性&#xff08;P&#xff09;&#xff0c;而不保证强一致性&#xff08;C&#xff09;。这种设计使得Eureka在分布式系统中能够应对各种故障和分区情况&#xff0c;保…

Java 原型模式、建造者模式、单例模式

原型模式、建造者模式 原型模式 原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;它允许你通过复制现有对象来创建新对象&#xff0c;而不是通过实例化类。这种模式在需要大量相似对象时非常有用&#xff0c;因为它可以减少创建对象的开销…

(leetcode算法题)155. 最小栈 901. 股票价格跨度

这两道题都是单调栈专题中的引子题目&#xff0c; 如果我们仔细分析题目&#xff0c;如果只是想得到当前历史数据中最小值和可以发现这两道题&#xff0c; 都不用使用一个额外的容器装以往所有的历史数据才能得到结果 对于155来说&#xff0c; 只需要维护最小栈就可以快速获…

数据结构与算法之二叉树: LeetCode 701. 二叉搜索树中的插入操作 (Ts版)

二叉搜索树中的插入操作 https://leetcode.cn/problems/insert-into-a-binary-search-tree/description/ 描述 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树返回插入后二叉搜索树的根节点。 输入数据 保…

第六章:网页设计

文章目录&#xff1a; 一&#xff1a;网页设计 1.基本概念 1.1 网页 1.2 网站 1.3 工具 2.HTML语言 2.1 基础 2.2 标记 2.2.1 结构 2.2.2 文本 2.2.3 功能 2.2.4 表单 2.3 属性 二&#xff1a;IIS 1.定义 2.主要功能 3.特点与优势 4.应用场景 4.1 安装IIS …