LeetCode146: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.
解题思路:
利用双向链表+hashtable实现
Cache中的存储空间往往是有限的,当Cache中的存储块被用完,而需要把新的数据Load进Cache的时候,我们就需要设计一种良好的算法来完成数据块的替换。LRU的思想是基于“最近用到的数据被重用的概率比较早用到的大的多”这个设计规则来实现的。
为了能够快速删除最久没有访问的数据项和插入最新的数据项,我们双向链表连接Cache中的数据项,并且保证链表维持数据项从最近访问到最旧访问的顺序。每次数据项被查询到时,都将此数据项移动到链表头部(O(1)的时间复杂度)。这样,在进行过多次查找操作后,最近被使用过的内容就向链表的头移动,而没有被使用的内容就向链表的后面移动。当需要替换时,链表最后的位置就是最近最少被使用的数据项,我们只需要将最新的数据项放在链表头部,当Cache满时,淘汰链表最后的位置就是了。
查找一个链表中元素的时间复杂度是O(n),每次命中的时候,我们就需要花费O(n)的时间来进行查找,怎么样才能提高查找的效率呢?当然是hashtable了,因为它的查找时间复杂度是O(1)。
实现代码:
#include <iostream>
#include <unordered_map> using namespace std;
/*
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.
*/ //双向链表节点
struct LRUNode
{
int key;
int val;
LRUNode *pre;
LRUNode *next;
LRUNode(int k = , int v = ):key(k), val(v),pre(NULL), next(NULL){
}
};
class LRUCache{
public:
LRUCache(int capacity):cap(capacity),size() {
head = new LRUNode();
tail = new LRUNode();
head->next = tail;
tail->pre = head; } int get(int key) {
LRUNode *t = hashtable[key];
if(t)//key在hashtable存在,则调整该key在链表中对应节点的位置,将其插入到最前面
{
//分离t节点
t->pre->next = t->next;
t->next->pre = t->pre;
//将t节点插入到头结点之后,即第一个数据节点
t->pre = head;
t->next = head->next;
head->next = t;
t->next->pre = t;
return t->val; }
else
return -; } void set(int key, int value) {
LRUNode *t = hashtable[key];
if(t)//key在hashtable存在,则更新value及调整该key对应节点在链表中位置,将其插入到第一个节点
{
t->val = value;
//分离t节点
t->pre->next = t->next;
t->next->pre = t->pre;
//将t节点插入到头结点之后,即第一个数据节点
t->pre = head;
t->next = head->next;
head->next = t;
t->next->pre = t;
return ; } if(size == cap)//如果双向链表容量已满即缓存容量已满,则将最近不使用的节点即链表最后一个数据节点删除
{
LRUNode *tmp = tail->pre;
tail->pre->pre->next = tail;
tail->pre = tmp->pre;
hashtable.erase(tmp->key);
delete tmp;
size--;
} //创建key对应的一个新节点,插入到最前面
LRUNode *node = new LRUNode(key, value); node->pre = head;
node->next = head->next;
head->next = node;
node->next->pre = node; hashtable[key] = node;//在hashtable添加key对应的表项 size++;//链表节点数++ }
private:
int cap;//链表容量即缓存容量
int size;//缓存当前使用量
LRUNode *head;//链表头结点,不存数据,
LRUNode *tail;//链表尾节点,不存数据
unordered_map<int,LRUNode*> hashtable;//hashtable,用作查找O(1)时间复杂度 };
int main(void)
{
LRUCache lrucache();
lrucache.set(,);
lrucache.set(,);
lrucache.set(,);
lrucache.set(,);
cout<<lrucache.get()<<endl;
cout<<lrucache.get()<<endl;
cout<<lrucache.get()<<endl; return ;
}
LeetCode146:LRU Cache的更多相关文章
- LeetCode题解: LRU Cache 缓存设计
LeetCode题解: LRU Cache 缓存设计 2014年12月10日 08:54:16 邴越 阅读数 1101更多 分类专栏: LeetCode 版权声明:本文为博主原创文章,遵循CC 4 ...
- LeetCode OJ:LRU Cache(最近使用缓存)
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- 【Leetcode146】LRU Cache
问题描述: 设计一个LRU Cache . LRU cache 有两个操作函数. 1.get(key). 返回cache 中的key对应的 val 值: 2.set(key, value). 用伪代码 ...
- LeetCode:146_LRU cache | LRU缓存设计 | Hard
题目:LRU cache Design and implement a data structure for Least Recently Used (LRU) cache. It should su ...
- [Swift]LeetCode146. LRU缓存机制 | LRU Cache
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- [LeetCode] LRU Cache 最近最少使用页面置换缓存器
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- 【leetcode】LRU Cache
题目简述: Design and implement a data structure for Least Recently Used (LRU) cache. It should support t ...
- LeetCode:LRU Cache
题目大意:设计一个用于LRU cache算法的数据结构. 题目链接.关于LRU的基本知识可参考here 分析:为了保持cache的性能,使查找,插入,删除都有较高的性能,我们使用双向链表(std::l ...
- LRU Cache实现
最近在看Leveldb源码,里面用到LRU(Least Recently Used)缓存,所以自己动手来实现一下.LRU Cache通常实现方式为Hash Map + Double Linked Li ...
随机推荐
- float数据类型研究,发现其能显示的有效数字极为有限
1. 范围 float和double的范围是由指数的位数来决定的. float的指数位有8位,而double的指数位有11位,分布如下: float: 1bit(符号位) 8bits(指数位) ...
- 矩形最小路径和 · Minimum Path Sum
[抄题]: 给定一个只含非负整数的m*n网格,找到一条从左上角到右下角的可以使数字和最小的路径. [思维问题]: [一句话思路]: 和数字三角形基本相同 [输入量]:空: 正常情况:特大:特小:程序里 ...
- Extended Backus–Naur Form
From Wikipedia, the free encyclopedia In computer science, Extended Backus–Naur Form (EBNF) is a fam ...
- iOS.AVCaptureSession
AVCaptureSession的使用容易freeze的问题 1. http://stackoverflow.com/questions/11905505/avcapturesession-stop- ...
- OpenSource.iOS.ProtobufWithObjective-C
2. 在iOS(Mac OS X)中使用protobuf 2.0 构建protoc A) 下载最新的protobuf版本 B) 依据README中的步骤依次进行 2.1 添加protobuf到工程中 ...
- restful发布服务
概述 REST 从资源的角度来观察整个网络,分布在各处的资源由URI确定,而客户端的应用通过URI来获取资源的表示方式.获得这些表徵致使这些应用程序转变了其状态.随着不断获取资源的表示方式,客户端应用 ...
- Laravel 本地化定义
1.配置本地化语言Laravel 的本地化语言配置项位于config/app.php: [php] view plain copy 'locale' => 'zh',//当前语言 'fallba ...
- 获得iframe 高度 ,各种浏览器
function fuFunctiondan(){ var frm=$("#z_div"); var iframeHeight=0; if (navigator.userAgent ...
- Can't use Subversion command line client: svn. Errors found while svn working copies detection.
idea 报错: Can't use Subversion command line client: svn. Errors found while svn working copies detect ...
- Realtek 8192cu 支持 Android Hotspot 软ap
http://www.cnblogs.com/bpasser/archive/2011/10/15/2213483.html Android 2.2 开始增加了WiFi Hotspot,可将Andro ...