Leetcode: LRU Cache

题目

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

 

思路

1. 双向链表支持常数时间增删元素, 单向链表配合 hash table 也可以实现, 但是实现相当复杂

2. hash table 存储链表中的元素

 

总结

1. 双向链表要处理的情况比单向链表更复杂

2. 单向链表处理时, 仅需考虑 head 的问题, 但双向链表则需要考虑

  a) 增元素时, 考虑链表是否为空即 head 问题

  b) 删元素时, 要考虑被删除的元素是否为 head 

  c) LRU 操作, 前移元素时, 需要考虑被前移的元素是否为 Head, 这一个 bug 浪费了 2 个小时

  d) 有一个优化, 即 LRU set miss 时, 不需要显式的删除再增加节点, 仅需将 tail 节点的 key, value 修改 然后 head 前进一步即可

 

代码

class Node {
public:int key, value;Node *next, *pre;Node(int _key, int _value):key(_key), value(_value), next(NULL), pre(NULL){}
};
class LRUCache{
public:int capacity;int curSize;unordered_map<int, Node*> mp;Node *head;LRUCache(int capacity) {this->capacity = capacity;curSize = 0;}int get(int key) {if(mp.find(key) == mp.end())return -1;int val = mp.find(key)->second->value;set(key, val);return val;}void set(int key, int value) {int ans = 0;if(mp.find(key) == mp.end())ans = -1;if(ans == -1) { // 新建一个 itemif(curSize >= capacity) { // 已满, 需要删除一个 itemif(capacity == 1) {mp.erase(mp.find(head->key));head->key = key;head->value = value;mp[key] = head;return;}else{	// 模拟删除队尾元素Node *tail = head->pre;mp.erase(mp.find(tail->key));tail->key = key;tail->value = value;head = tail;mp[key] = head;return;}}// 未满, 添加元素if(curSize == 0) {head = new Node(key, value);head->pre = head;head->next = head;mp[key] = head;curSize++;return ;}else {Node *al = new Node(key, value);al->pre = head->pre;al->next = head;al->pre->next = al;head->pre = al;head = al;mp[key] = al;curSize++;return;}}else{if(head->key == key) {head->value = value;mp[key] = head;return;}//cout << "here" << endl;Node *mid = mp.find(key)->second;mid->next->pre = mid->pre;mid->pre->next = mid->next;mid->value = value;mid->next = head;mid->pre = head->pre;head->pre = mid;mid->pre->next = mid;head = mid;mp[key] = mid;	// 修改 mp[key]return;}}
};

  

 

Update 

#include <iostream>
#include <map>
using namespace std;class ListNode1 {
public:ListNode1(int _key, int _val) {key = _key;val = _val;pre = next = NULL;}ListNode1 *pre;int key;int val;ListNode1 *next;
};class LRUCache{
public:LRUCache(int capacity) {this->capacity = capacity;head = NULL;size = 0;}int get(int key) {if(mp.count(key) == 0)return -1;int value = mp[key]->val;set(key, value);return value;}void set(int key, int value) {if(capacity == 1) {mp.clear();head = new ListNode1(key, value);mp[key] = head;return;}if(mp.count(key) > 0) {ListNode1 *curNode = mp[key];curNode->val = value;if(curNode == head)return;curNode->pre->next = curNode->next;curNode->next->pre = curNode->pre;head->pre->next = curNode;curNode->pre = head->pre;curNode->next = head;head->pre = curNode;head = curNode;return;}if(size < capacity) {size ++;ListNode1 *newNode = new ListNode1(key, value);mp[key] = newNode;if(size == 1) {newNode->pre = newNode;newNode->next = newNode;head = newNode;return;}head->pre->next = newNode;newNode->pre = head->pre;newNode->next = head;head->pre = newNode;head = newNode;return;}// size >= capacityListNode1 *tail = head->pre;mp.erase(mp.find(tail->key));mp[key] = tail;tail->key = key;tail->val = value;head = tail;}
private:int capacity;int size;map<int, ListNode1*> mp;ListNode1 *head;
};

 

转载于:https://www.cnblogs.com/xinsheng/p/3514968.html

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

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

相关文章

Day-17: 网络编程

---恢复内容开始--- 现有的互联网通讯方式&#xff0c;是服务器端的进程与客户端进程的通信。Python中进行网络编程&#xff0c;就是在Python程序本身这个进程内&#xff0c;连接别的服务器进程的通信端口进行通信。 互联网协议上包含了上百种协议标准&#xff0c;但是&#xf…

启动MySQL报错

当在linux系统中启动mysql服务的时候service mysqld start时 报&#xff1a;Another MySQL daemon already running with the same unix socket. 解决办法。 原因多个Mysql进程使用了同一个socket。 两个方法解决&#xff1a; 第一个是立即关机 使用命令 shutdown -h now 关机&…

计算机应用基础教程作业脑图 车辆工程学院 冯大昕

转载于:https://www.cnblogs.com/FengTang/p/7553055.html

UML该元素的行为为基础的元素

&#xfeff;&#xfeff;Behavioral thingsare the dynamic parts of UML models. These are the verbs of a model, representing behavior over time and space. In all, there are three primary kinds of behavioral things. 行为元件是UML模型的动态部分&#xff0e;它们…

EasyDSS高性能流媒体服务器前端重构(五)- webpack + vue-router 开发单页面前端实现按需加载 - 副本...

为了让页面更快完成加载, 第一时间呈现给客户端, 也为了帮助客户端节省流量资源, 我们可以开启 vue-router 提供的按需加载功能, 让客户端打开页面时, 只自动加载必要的资源文件, 当客户端操作页面, 切换功能模块, 触发页面路由变化时, 再去加载相应需要的资源. 本系列博客的前…

可工作的软件胜过面面俱到的文档

正在看一本书&#xff0c;书上讲到一个观点&#xff0c;“可工作的软件胜过面面俱到的文档”&#xff0c;这一点我一直都很认可&#xff0c;在平时工作中也是依据这一观点不写详细设计文档就开始编码&#xff0c;设计过程只做比较粗略的概要设计&#xff0c;但是涉及到数据库设…

解密阿里云七武器之高性能消息服务ONS

2019独角兽企业重金招聘Python工程师标准>>> 7月22日&#xff0c;首届阿里云分享日上&#xff0c;阿里云正式对外发布了企业级互联网架构解决方案&#xff0c;该服务由EDAS应用框架、ONS消息队列、DRDS分布式数据库组成&#xff0c;能有效解决企业上云后网站过载、性…

php动态数组的用法

// 创建连接 $con new mysqli($servername, $username, $password, $dbname); // Check conection if ($con->connect_error) {die("连接失败: " . $con->conect_error); }$sql "SELECT * FROM table limit 0,1000"; $result $con->query($sql…

MySQL划重点-查询-条件

查询的基本语法select * from 表名; 消除重复行在 select 后面列前使用distinct 可以消除重复的行 select distinct gender from students;一、条件 使用where子句对表中的数据筛选&#xff0c;结果为true的行会出现在结果集中语法如下 select * from 表名 where 条件;select *…

高数.........

高数70你敢信&#xff1f;&#xff1f;&#xff1f;临考前各种复习做卷子 各种认真 考试的时候感觉题目也都能做 尼玛连上平时分才给我70&#xff1f; 特么我是不信 打电话问问老师 如果没录错果断重修 郁闷转载于:https://www.cnblogs.com/ahu-shu/p/3520249.html

windows服务器下的ftp server搭建

软件下载链接&#xff1a;http://pan.baidu.com/s/1eQJbmUY ftpserver1.下载后打开。2.运行安装3.安装目录选择。这里我选择安装在C盘的FTP目录下&#xff0c;直接填写即可。这个安装目录可随意设置。4.安装启动。查看使用教程&#xff0c;添加用户名&#xff0c;设置密码&a…

WordPress获取当前分类ID的四种方法

WordPress获取当前分类ID的四种方法 时间: 2015-01-05 所属栏目: Wordpress教程 作者: WP管理员之家 关键词: wordpress,分类ID 关注热度&#xff1a; 4,346 次 (1条) WordPress获取当前分类ID的方法有很多&#xff0c;今天我来给大家总结一下吧,wordpress主题定制专家-WP管理…

linux笔记_20150825_linux下的软件工具唠叨下

这些都是书上看到的&#xff0c;有些工具我也没有完全用过。先记下来再说。闲着也是闲着。 1.linux下常见的语言及编程环境:c/c/java/perl/fortan等. 2.图形环境:gnome/kde/gimp/windowmaker/icewm等. 3.编辑器:xemacs/vim/gedit/pico等. 4.shells&#xff1a;bash/tcsh/ash/cs…

扩展编写jquery插件的方法

比如要扩展验证功能&#xff08;jquery.validate.js&#xff09;中的 messages: { required: "This field is required.", remote: "Please fix this field.", email: "Please enter a valid email address.", url: "Please enter a valid …

WordPress窗体化侧边栏

窗体化侧边栏是一个支持 Widget 的侧边栏或者说是窗体化&#xff08;widgetized&#xff09;的侧边栏几乎是 WordPress 主题的标准。 首先&#xff0c;什么是窗体化&#xff08;widgetizing&#xff09;呢&#xff1f;简单的说&#xff0c;窗体化就是能够通过拖拉就能够整理侧边…

EditPlus3 添加 PHP代码格式化

https://www.jb51.net/softs/23113.html 整合PHPCB到EditPlus&#xff1a; EidtPlus&#xff1a;工具》配置用户工具…》添加工具&#xff1a; 菜单文本&#xff1a;PHPCB 命令&#xff1a;浏览到PHPCB程序。 参数&#xff1a;--space-after-if --optimize-eol --space-aft…

1-17

今天很慵懒啊&#xff0c;啥事也没做&#xff0c;把高精度复习了一遍&#xff08;hdu1002&#xff09;。 首先俩字符串数组输入&#xff0c;然后按字符串的长度逆序转到整形数组里 &#xff08;主要是为了把数值的最低位移动到数组的最低位&#xff0c;方便进位&#xff09;&am…

FTP下载导致Zip解压失败的原因

情形&#xff1a;网关通过FTP下载快钱对账文件时通过Apache下commons-net的commons-net-3.5.jar进行封装&#xff0c;对账文件中有中文和英文的文字,大部分情况下能够下载成功&#xff0c;而且也能解压成功。但是偶尔会出现下载了zip的文件&#xff0c;但是解压失败的情况。解决…

SNMP学习之结构体snmp_secmod_def

此结构体中定义了各个回调函数&#xff0c;在函数init_ksm&#xff08;E:\code\net-snmp-5.4.2.1\snmplib&#xff09;中进行了初始化。 void init_ksm(void) { struct snmp_secmod_def *def; // 申请内存 def SNMP_MALLOC_STRUCT(snmp_secmod_def); // 初始化回调函数 def-…

iOS 多参数 ...NS_REQUIRES_NIL_TERMINATION 的写法

1.很早就看到项目里面有下面这样的写法 1 - (id) initWithTitle:(NSString *)title items:(MXContextMenuItem *)item, ... NS_REQUIRES_NIL_TERMINATION; 2.查了点资料&#xff0c;自己练习了下&#xff0c;试着写了个 1 //.h 2 - (NSString *)addMoreArguments:(NSString …