LeetCode 146. LRU CacheLRU缓存机制 (C++/Java)
题目:
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.
get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.put(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.
The cache is initialized with a positive capacity.
Follow up:
Could you do both operations in O(1) time complexity?
Example:
LRUCache cache = new LRUCache( 2 /* capacity */ ); cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // returns 1
cache.put(3, 3); // evicts key 2
cache.get(2); // returns -1 (not found)
cache.put(4, 4); // evicts key 1
cache.get(1); // returns -1 (not found)
cache.get(3); // returns 3
cache.get(4); // returns 4
分析:
设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。
获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。
按照所给的例子看一下cache内部是如何变化的。
| front | back | result | |
| put(1, 1) | (1, 1) | ||
| put(2, 2) | (2, 2) | (1, 1) | |
| get(1) | (1, 1) | (2, 2) | 1 |
| put(3, 3) | (3, 3) | (1, 1) | |
| get(2) | (3, 3) | (1, 1) | -1 |
| put(4, 4) | (4, 4) | (3, 3) | |
| get(1) | (4, 4) | (3, 3) | -1 |
| get(3) | (3, 3) | (4, 4) | 3 |
| get(4) | (4, 4) | (3, 3) | 4 |
很清楚的就理解了LRU的机制,当get的key在cache中已经存在时,就将存储的内容放到最前面,get的key不存在时就返回-1。
put的新的key-value时,如果达到了容量上限,就删除一个最近最少使用的,实际上也是队尾的元素,然后将新的key-value存储到最前面。
因为我们每次要O(1)的复杂度,所以可以使用hashmap来get数据,而当容量达到上限时,要删除最近最少使用的,且要在最前面put进新的数据,要使用一个双向链表,来保证O(1)的时间复杂度。
java中可以使用LinkeHashMap来实现LRU缓存。
程序:
C++
class LRUCache {
public:
LRUCache(int capacity) {
cap = capacity;
}
int get(int key) {
auto it = map.find(key);
if(it == map.end())
return -1;
l.splice(l.begin(), l, it->second);
return it->second->second;
}
void put(int key, int value) {
auto it = map.find(key);
if(it != map.end()){
l.erase(it->second);
}
l.push_front(make_pair(key, value));
map[key] = l.begin();
if (map.size() > cap) {
int k = l.rbegin()->first;
l.pop_back();
map.erase(k);
}
}
private:
int cap;
list<pair<int, int>> l;
unordered_map<int, list<pair<int, int>>::iterator> map;
};
Java
class LRUCache {
public LRUCache(int capacity) {
this.cap = capacity;
this.map = new HashMap<>();
this.dummyHead = new Node(0, 0);
this.tail = new Node(0, 0);
dummyHead.prev = null;
dummyHead.next = tail;
tail.prev = dummyHead;
tail.next = null;
}
public int get(int key) {
if(!map.containsKey(key))
return -1;
Node node = map.get(key);
removeNode(node);
addToHead(node);
return node.val;
}
public void put(int key, int value) {
if(map.containsKey(key)){
Node node = map.get(key);
removeNode(node);
map.remove(key);
size--;
}
Node node = new Node(key, value);
map.put(key, node);
if(size < cap){
addToHead(node);
size++;
}else {
map.remove(tail.prev.key);
removeNode(tail.prev);
addToHead(node);
}
}
private void removeNode(Node node){
node.prev.next = node.next;
node.next.prev = node.prev;
}
private void addToHead(Node node){
node.next = dummyHead.next;
node.next.prev = node;
dummyHead.next = node;
node.prev = dummyHead;
}
class Node{
int key;
int val;
Node prev;
Node next;
public Node(int key, int val){
this.key = key;
this.val = val;
}
}
private int cap;
private Map<Integer, Node> map;
private Node dummyHead;
private Node tail;
private int size;
}
class LRUCache {
public LRUCache(int capacity) {
this.capacity = capacity;
map = new LinkedHashMap<>();
}
public int get(int key) {
if(map.containsKey(key)) {
int value = map.get(key);
map.remove(key);
map.put(key, value);
return value;
}
return -1;
}
public void put(int key, int value) {
if(map.containsKey(key)) {
map.remove(key);
}
map.put(key, value);
if(map.size() > capacity) {
map.remove(map.keySet().iterator().next());
}
}
private int capacity;
private LinkedHashMap<Integer, Integer> map;
}
LeetCode 146. LRU CacheLRU缓存机制 (C++/Java)的更多相关文章
- [leetcode]146. LRU CacheLRU缓存
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- 重学数据结构(三)——使用单链表实现LRU淘汰缓存机制
使用单链表实现LRU(Least Recently Used)淘汰缓存机制 需求:存在一个单链表,在单链表尾部的都是越早之前添加的元素. 当元素被访问到时,会添加进缓存(也就是这个单链表中). 如果这 ...
- Java实现 LeetCode 146 LRU缓存机制
146. LRU缓存机制 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - ...
- [Leetcode]146.LRU缓存机制
Leetcode难题,题目为: 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key ...
- LeetCode 146. LRU缓存机制(LRU Cache)
题目描述 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果密钥 (k ...
- Leetcode 146. LRU 缓存机制
前言 缓存是一种提高数据读取性能的技术,在计算机中cpu和主内存之间读取数据存在差异,CPU和主内存之间有CPU缓存,而且在内存和硬盘有内存缓存.当主存容量远大于CPU缓存,或磁盘容量远大于主存时,哪 ...
- 如何利用缓存机制实现JAVA类反射性能提升30倍
一次性能提高30倍的JAVA类反射性能优化实践 文章来源:宜信技术学院 & 宜信支付结算团队技术分享第4期-支付结算部支付研发团队高级工程师陶红<JAVA类反射技术&优化> ...
- leetcode 146. LRU Cache 、460. LFU Cache
LRU算法是首先淘汰最长时间未被使用的页面,而LFU是先淘汰一定时间内被访问次数最少的页面,如果存在使用频度相同的多个项目,则移除最近最少使用(Least Recently Used)的项目. LFU ...
- [LeetCode] 146. LRU Cache 最近最少使用页面置换缓存器
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- [LeetCode] 146. LRU Cache 近期最少使用缓存
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
随机推荐
- axiso封装
import axios from 'axios';import {Message } from 'element-ui'//element-ui提示框组件import config from './ ...
- 【Oracle】预定义说明的部分 ORACLE 异常错误(EXCEPTION)
预定义说明的部分 ORACLE 异常错误(EXCEPTION) 参考链接:https://www.cnblogs.com/thescentedpath/p/errordeal.html EXCEPTI ...
- 第壹課-Install:Mirth Connect在Win10下的安装步骤
1.安装JDK,推荐安装JDK8 64位,版本jdk-8u201-windows-x64.exe. 安装JDK后,同时必须配置win10的系统环境变量[示例如下]: JAVA_HOME : F:\Ja ...
- 开篇:Mirth Connect系统集成与数据交换引擎
Mirth最初的目的是作为HL7接口引擎('引擎'释意:IT方面的术语,指经包装过的函数库,方便别人调用:如搜索引擎.图形引擎.物理引擎等),HL7 v2.x和HL7 v3标准通常在医疗系统间用于系统 ...
- 力扣1083(MySQL)-销售分析Ⅲ(简单)
题目: Table: Product Table: Sales 编写一个SQL查询,报告2019年春季才售出的产品.即仅在2019-01-01至2019-03-31(含)之间出售的商品. 以 任意顺序 ...
- 力扣385(java)-迷你语法分析器(中等)
题目: 给定一个字符串 s 表示一个整数嵌套列表,实现一个解析它的语法分析器并返回解析的结果 NestedInteger . 列表中的每个元素只可能是整数或整数嵌套列表 示例 1: 输入:s = &q ...
- Spark 大数据处理最佳实践
开源大数据社区 & 阿里云 EMR 系列直播 第十一期 主题:Spark 大数据处理最佳实践 讲师:简锋,阿里云 EMR 数据开发平台 负责人 内容框架: 大数据概览 如何摆脱技术小白 Spa ...
- shell 调试方法
shell 在 linux 系统中比较常见,简单的脚本可以看着确实没难度,但是当脚本功能复杂后,看起来就不那么流畅了,所以掌握一些调试方式还是很有必要的,这里我收集了一次常用的调试方式. shell调 ...
- Ubuntu 安装谷歌中文输入法
Ubuntu 安装谷歌中文输入法 下载谷歌拼音:sudo apt-get install fcitx-googlepinyin 点击设置: 第一次打开需要点击安装: 设置完成后重启系统 点击右上角键盘 ...
- 关于sql server导出csv格式文件的身份证号乱码问题处理办法
1.使用SQL Server数据库经常会遇到导出大量数据的情况,例如导出40万条数据,虽然EXCL支持可以放入百万的数据,但是使用数据库复制,粘贴到EXCL表格时,数据库会提示溢出的情况,如下图所示: ...