LRU Cache 双向链表以及STL list实现----面试常考

双向链表版本:
#include <bits/stdc++.h>
using namespace std;
struct Node{int key, value;Node* prev;Node* next;Node():key(0), value(0), prev(nullptr), next(nullptr){}Node(int k, int v):key(k), value(v), prev(nullptr), next(nullptr){}
};
class LRUCache{
private:int capacity_;int size_;Node* head;Node* tail;unordered_map<int, Node*> cache_;
public:LRUCache(int capacity): capacity_(capacity), size_(0){head = new Node();tail = new Node();head->next = tail;tail->prev = head;}void removeNode(Node* node){node->prev->next = node->next;node->next->prev = node->prev;}void addToHead(Node* node){node->next = head->next;node->prev = head;head->next->prev = node;head->next = node;}void moveToHead(Node* node){removeNode(node);addToHead(node);}Node* removeTail(){auto node = tail->prev;removeNode(node);return node;}int get(int key){if(cache_.find(key) != cache_.end()){moveToHead(cache_[key]);return cache_[key]->value;}return -1;}void put(int key, int value){if(cache_.find(key) != cache_.end()){moveToHead(cache_[key]);cache_[key]->value = value;}else{if(size_ == capacity_){auto node = removeTail();cache_.erase(node->key);delete node;--size_;}auto node = new Node(key, value);addToHead(node);cache_.insert({key, node});++size_;}}~LRUCache(){while(head){auto node = head;head = head->next;delete node;}}void print(){cout << "=================" << endl;auto node = head->next;while(node != tail){cout << "[" << node->key << " " << node->value << "]" << endl;node = node->next;}}
};
int main(){auto lru = new LRUCache(2);lru->put(1, 1);lru->put(2, 2);lru->print();lru->put(3, 3);lru->print();cout << lru->get(2) << endl;lru->print();lru->put(4, 4);lru->print();cout << lru->get(1) << endl;lru->print();cout << lru->get(3) << endl;return 0;
}

手写双向链表版本比较简单,在纸上画一画就能想通!

STL的list版本:
using pi = pair<int, int>;
class LRUCache {
public:LRUCache(int capacity):capacity_(capacity){}/*** 根据给定的键获取缓存中的值。* 如果键存在于缓存中,则将该键值对移动到缓存的前端,并返回对应的值。* 如果键不存在于缓存中,则返回-1。* * @param key 要查询的键。* @return 存储在缓存中的键对应的值,如果键不存在则返回-1。*/int get(int key) {// 检查键是否存在于缓存中if(key_table_.count(key)){// 获取键对应的节点auto node = key_table_[key];// 从节点中提取值int value = node->second;// 从缓存中删除节点,因为它即将被移动到前端cache_.erase(node);// 将键值对移动到缓存的前端cache_.push_front({key, value});// 更新键在映射表中的指针,指向移动到前端的新节点key_table_[key] = cache_.begin();// 返回键对应的值return value;}// 如果键不存在,返回-1return -1;}/*** 将键值对(key, value)放入缓存。* 如果键已经存在,则更新对应的值,并从缓存中移除该键值对,以便重新插入以维护LRU顺序。* 如果缓存已满,则移除最不常访问的键值对,为新键值对腾出空间。* * @param key 要放入缓存的键。* @param value 要放入缓存的值。*/void put(int key, int value) {// 如果键已经存在,则获取对应的节点if(key_table_.count(key)){auto node = key_table_[key];int value = node->second;// 从缓存中移除该节点,因为待会要重新插入以维护LRU顺序cache_.erase(node);}else{// 如果缓存已满,则移除最不常访问的键值对if(cache_.size() == capacity_){auto kv = cache_.back();int k = kv.first, v = kv.second;cache_.pop_back();key_table_.erase(k);}}// 将新的键值对插入到缓存的前端,并更新键映射表cache_.push_front({key, value});key_table_[key] = cache_.begin();}
private:unordered_map<int, list<pi>::iterator> key_table_; list<pi> cache_;   // 缓存int capacity_;   
};

主要用了迭代器,对于初学者可能难以理解。可以看我的下一篇博客,详细阐述了迭代器设计思想!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/40508.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【IT领域新生必看】Java中的对象创建魔法:小白也能掌握的五种方法

文章目录 引言为什么需要创建对象&#xff1f;创建对象的五种常见方式1. 使用 new 关键字示例&#xff1a; 2. 使用反射示例&#xff1a; 3. 使用克隆示例&#xff1a; 4. 使用序列化和反序列化示例&#xff1a; 5. 使用工厂方法示例&#xff1a; 选择合适的对象创建方式总结 引…

Spring容器Bean之XML配置方式

一、首先看applicationContext.xml里的配置项bean 我们采用xml配置文件的方式对bean进行声明和管理&#xff0c;每一个bean标签都代表着需要被创建的对象并通过property标签可以为该类注入其他依赖对象&#xff0c;通过这种方式Spring容器就可以成功知道我们需要创建那些bean实…

IPython代码块粘贴秘籍:效率与技巧的完美结合

标题&#xff1a;IPython代码块粘贴秘籍&#xff1a;效率与技巧的完美结合 在数据科学和Python编程的日常实践中&#xff0c;经常需要在IPython环境中快速有效地粘贴代码块。这个过程虽小&#xff0c;却对提升工作效率至关重要。本文将详细介绍如何在IPython中粘贴代码块&…

comsol随机材料参数赋值

comsol随机材料参数赋值 在comsol中定义外部matlab函数 在comsol中定义外部matlab函数 首选项&#xff0c;安全性&#xff0c;允许 材料中&#xff0c;将杨氏模量更改为变量函数 计算 应力有波动&#xff0c;可见赋值成功 也可以看到赋值的材料参数&#xff1a;

植物大战僵尸杂交版V2.1+修改器+融合版

植物大战僵尸杂交版v2.1 新增新植物&#xff0c;全新模式与玩法&#xff01; 内含窗口放大工具与修改器 主播同款游戏&#xff0c;下载使用即可&#xff01; 链接: https://pan.baidu.com/s/1znjbqgBSdqTJWZLBOhe5hA?pwdj6ra 提取码: j6ra

vulnhub--IMF

环境 攻击机&#xff1a;192.168.96.4 靶机&#xff1a;ip未知 主机探测 确定靶机ip为32的主机 端口扫描 访问80端口 外围打点 在contact.php页面源码中找到了flag1 之后没啥突破 但查看网络后发现contact.php页面请求的三个js文件的文件名很有特点&#xff0c;猜测是base64编码…

模型优化调参利器贝叶斯优化bayesian-optimization实践

早在之前很多项目尤其是预测类型的项目中&#xff0c;就已经比较广泛地在实用贝叶斯优化库了&#xff0c;这是一个非常出色的纯python实现的项目&#xff0c;地址在这里&#xff0c;如下所示&#xff1a; 写这篇文章主要有两个目的&#xff0c;一方面是觉得这个工具库挺不错的值…

零基础做项目---五子棋对战---day01

创建项目 这里使用阿里云服务器 https://start.aliyun.com/ 勾选 MyBatis Framework (在SQL分类下)MySQL Driver (在SQL分类下)WebSocket (在Messaging分类下)Spring Web (在Web分类下) 项目结构 消息发送机制 按照当前已有的知识&#xff0c;主要是HTTP HTTP自身是难以实现这…

c++ 里如何检测内存泄露:比如用了 new ,但没有用 delete

&#xff08;1 方法一&#xff09; 用 MFC 框架的 F5 不带断点的调试。可以在输出窗口提示是否有内存泄露。 &#xff08;2 方法二&#xff09; &#xff0c;在 main 函数中添加如下代码&#xff0c;用 F5 不带断点的调试&#xff1a; int main() {_CrtSetDbgFlag( _CRTDBG_A…

vue.js微商城后台管理系统

一.需要运行的效果 20240701-231456 二.代码&#xff08;解析&#xff09; 首先&#xff0c;为项目添加依赖&#xff1a; yarn add element-plus --save yarn vue-router4 --save 新建一个项目包&#xff0c;然后命名为商品管理&#xff0c;在components中新建几个vue文件。 …

React Hooks 深度解析

Hooks简介 诞生背景&#xff1a; 在React 16.8之前的版本中&#xff0c;组件主要分为函数组件和类组件两大类。函数组件简单轻量&#xff0c;但不支持状态&#xff08;state&#xff09;和生命周期方法&#xff1b;而类组件虽然功能强大&#xff0c;但编写和维护起来相对复杂。…

驱动开发系列-如何与硬件通信

目录 一:概述 二:I/O端口和I/O内存的概念 三:硬件寄存器(I/O寄存器)和内存 四:使用I/O端口 一:概述 驱动程序是软件与硬件之间的抽象层;因此,它需要与这两者对话,本文将向你展示驱动程序如何与硬件对话。并介绍I/O端口和I/O内存的概念。 二:I/O端口和I/O…

C++新特性

C新特性主要体现在语法改进和标准库扩充两个方面。以下是一些主要的C新特性&#xff1a; 语法改进 统一的初始化方法&#xff1a;C11扩大了用大括号括起的列表&#xff08;初始化列表&#xff09;的使用范围&#xff0c;使其可用于所有的内置类型和用户自定义的类型。这种定义…

【C语言】指针(1)--入门理解

目录 一、内存和地址 二、指针变量和地址 三、指针变量类型的意义 一、内存和地址 只要讲指针就离不开内存 因为指针就是访问内存的 计算上CPU&#xff08;中央处理器&#xff09;在处理数据的时候&#xff0c;需要的数据是在内存中读取的&#xff0c;处理后的数 据也会放…

PY32F030高性能单片机,主频高达48M,最大64 KB 闪存,8 KB SRAM

PY32F030是普冉的一颗32位高性能MCU&#xff0c;采用32 位 ARM Cortex-M0 内核&#xff0c;高达16~64 Kbytes Flash 和 2~8 Kbytes SRAM 存储器&#xff0c;最高 48 MHz 工作频率。PY32F030 单片机的工作温度范围为 -40 ~ 105 C&#xff0c;工作电压范围为1.7 ~ 5.5 V&#xff…

Centos7删除MariaDB

在 CentOS 7 上删除 MariaDB 可以通过 yum 包管理器来完成。以下是一步一步的指导&#xff1a; 打开终端&#xff1a;首先&#xff0c;你需要打开你的 CentOS 7 系统的终端。 停止 MariaDB 服务&#xff08;如果正在运行&#xff09;&#xff1a;在卸载 MariaDB 之前&#xff…

IDEA实现远程Debug的步骤与方法

IDEA实现远程Debug的步骤与方法 在软件开发过程中&#xff0c;远程Debug是一个非常重要的功能&#xff0c;它允许开发者在本地IDE中调试远程服务器上的应用程序。IntelliJ IDEA作为一款强大的Java开发工具&#xff0c;提供了丰富的远程Debug功能。本文将详细介绍如何使用IDEA实…

多语言版在线出租车预订完整源码+用户应用程序+管理员 Laravel 面板+ 司机应用程序最新版源码

源码带PHP后台客户端源码 Flutter 是 Google 开发的一款开源移动应用开发 SDK。它用于开发 Android 和 iOS 应用&#xff0c;也是为 Google Fuchsia 创建应用的主要方法。Flutter 小部件整合了所有关键的平台差异&#xff0c;例如滚动、导航、图标和字体&#xff0c;可在 iOS 和…

DevOps实战:使用GitLab+Jenkins+Kubernetes(k8s)建立CI_CD解决方案

一.系统环境 本文主要基于Kubernetes1.21.9和Linux操作系统CentOS7.4。 服务器版本docker软件版本Kubernetes(k8s)集群版本CPU架构CentOS Linux release 7.4.1708 (Core)Docker version 20.10.12v1.21.9x86_64CI/CD解决方案架构图:CI/CD解决方案架构图描述:程序员写好代码之…

ASP.NET MVC-razor编写-2-svg中使用js+添加事件监听

环境&#xff1a;win10 效果 初始状态&#xff1a; 鼠标移入某个text&#xff08;比如KS primer&#xff09;时&#xff0c;text和连接的线条与箭头都变色&#xff1a; 鼠标移出时回复正常。 如果是移入另一种红色的text&#xff08;比如Cell Sceening Tag&#xff09;&…