题目:

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的更多相关文章

  1. LeetCode题解: LRU Cache 缓存设计

    LeetCode题解: LRU Cache 缓存设计 2014年12月10日 08:54:16 邴越 阅读数 1101更多 分类专栏: LeetCode   版权声明:本文为博主原创文章,遵循CC 4 ...

  2. LeetCode OJ:LRU Cache(最近使用缓存)

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  3. 【Leetcode146】LRU Cache

    问题描述: 设计一个LRU Cache . LRU cache 有两个操作函数. 1.get(key). 返回cache 中的key对应的 val 值: 2.set(key, value). 用伪代码 ...

  4. LeetCode:146_LRU cache | LRU缓存设计 | Hard

    题目:LRU cache Design and implement a data structure for Least Recently Used (LRU) cache. It should su ...

  5. [Swift]LeetCode146. LRU缓存机制 | LRU Cache

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  6. [LeetCode] LRU Cache 最近最少使用页面置换缓存器

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  7. 【leetcode】LRU Cache

    题目简述: Design and implement a data structure for Least Recently Used (LRU) cache. It should support t ...

  8. LeetCode:LRU Cache

    题目大意:设计一个用于LRU cache算法的数据结构. 题目链接.关于LRU的基本知识可参考here 分析:为了保持cache的性能,使查找,插入,删除都有较高的性能,我们使用双向链表(std::l ...

  9. LRU Cache实现

    最近在看Leveldb源码,里面用到LRU(Least Recently Used)缓存,所以自己动手来实现一下.LRU Cache通常实现方式为Hash Map + Double Linked Li ...

随机推荐

  1. float数据类型研究,发现其能显示的有效数字极为有限

    1. 范围  float和double的范围是由指数的位数来决定的.  float的指数位有8位,而double的指数位有11位,分布如下:  float:  1bit(符号位) 8bits(指数位) ...

  2. 矩形最小路径和 · Minimum Path Sum

    [抄题]: 给定一个只含非负整数的m*n网格,找到一条从左上角到右下角的可以使数字和最小的路径. [思维问题]: [一句话思路]: 和数字三角形基本相同 [输入量]:空: 正常情况:特大:特小:程序里 ...

  3. Extended Backus–Naur Form

    From Wikipedia, the free encyclopedia In computer science, Extended Backus–Naur Form (EBNF) is a fam ...

  4. iOS.AVCaptureSession

    AVCaptureSession的使用容易freeze的问题 1. http://stackoverflow.com/questions/11905505/avcapturesession-stop- ...

  5. OpenSource.iOS.ProtobufWithObjective-C

    2. 在iOS(Mac OS X)中使用protobuf 2.0 构建protoc A) 下载最新的protobuf版本 B) 依据README中的步骤依次进行 2.1 添加protobuf到工程中 ...

  6. restful发布服务

    概述 REST 从资源的角度来观察整个网络,分布在各处的资源由URI确定,而客户端的应用通过URI来获取资源的表示方式.获得这些表徵致使这些应用程序转变了其状态.随着不断获取资源的表示方式,客户端应用 ...

  7. Laravel 本地化定义

    1.配置本地化语言Laravel 的本地化语言配置项位于config/app.php: [php] view plain copy 'locale' => 'zh',//当前语言 'fallba ...

  8. 获得iframe 高度 ,各种浏览器

    function fuFunctiondan(){ var frm=$("#z_div"); var iframeHeight=0; if (navigator.userAgent ...

  9. 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 ...

  10. Realtek 8192cu 支持 Android Hotspot 软ap

    http://www.cnblogs.com/bpasser/archive/2011/10/15/2213483.html Android 2.2 开始增加了WiFi Hotspot,可将Andro ...