题目:

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. centos 网卡聚合及Cisco交换机链路聚合

    一.配置环境 centos 系统.网卡1口和2口做链路聚合.    交换机网口 6口和7口. 二.服务器操作步骤 centos 6 1.创建一个channel bonding interface #v ...

  2. 清明梦超能力者黄YY(idx数组)

    清明梦超能力者黄YY https://www.nowcoder.com/acm/contest/206/I 题目描述 黄YY是一个清明梦超能力者,同时也是一个记忆大师.他能够轻松控制自己在梦中的一切, ...

  3. GridView,datalist添加序号列

    GridView添加序号列:这个是经常需要的一个功能 <asp:TemplateField HeaderText="序号"> <ItemTemplate> ...

  4. UVa 11988 Broken Keyboard (a.k.a. Beiju Text)(链表)

    You're typing a long text with a broken keyboard. Well it's not so badly broken. The only problem wi ...

  5. 排序矩阵中的从小到大第k个数 · Kth Smallest Number In Sorted Matrix

    [抄题]: 在一个排序矩阵中找从小到大的第 k 个整数. 排序矩阵的定义为:每一行递增,每一列也递增. [思维问题]: 不知道应该怎么加,因为不是一维单调的. [一句话思路]: 周围两个数给x或y挪一 ...

  6. 3sum, 3sum closest

    [抄题]: Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find ...

  7. c#中@的3种作用

    以前只知道@在C#中为了写文件路径的\不要加转义符而在前面加上@标识符,没想到@还有其他的作用 1.忽略转义字符例如 string fileName = "D:\\文本文件\\text.tx ...

  8. phpcms与discuz的ucenter整合

    1.安装phpcms系统,域名为pc.me   2.安装discuz,并选择安上uc_server,域名为dz.me   3.在phpcms下phpsso的系统设置   4.到ucenter管理中心- ...

  9. [PHP]require include

  10. CreateMutex用法

    1.  CreateMutex只是创建了一把锁,  这把锁你用来锁门还是锁抽屉还是锁你对象的内裤都由你自己决定. 2. lpName是指定这把锁的名字.  你要不给这把锁取个名字都可以.  只是有了相 ...