题目:

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. 如何禁止浏览器自动填充非登陆input的账号和密码?

    发现浏览器填充密码的方式,那就是,找到页面上第一个type为password的input填充.发现了这个规律后,很自然的就想到了,是不是可以在真正的password前面加一个隐藏的password,形 ...

  2. Spring依赖注入:基于xml配置

    基础接口 BeanFactory.ApplicationContext. BeanFactory用于创建并管理.获取各种类的对象. ApplicationContext从BeanFactory派生而来 ...

  3. 取消svn add

    svn commit之前,add的东西都可以取消. 通过先执行svn cleanup,再执行svn revert --recursive example_folder.

  4. MySQL优化update操作

    http://www.cnblogs.com/jevo/p/3314928.html 用replace代替delete和insert. insert用批量. 用延迟(类似于缓冲,会否饿死) 大量插入, ...

  5. ios 8 联系人ABPeoplePickerNavigationController

    一. ios 联系人ABPeoplePickerNavigationControllerDelegate方法,新添加下面两个联系人选中方法,适配iOS8需要实现 // Called after a p ...

  6. html标签的总结-重复

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  7. Codeforces 658A. Robbers' watch 模拟

    A. Robbers' watch time limit per test: 2 seconds memory limit per test: 256 megabytes input: standar ...

  8. This page contains the following error

    解决办法:将header头注释掉 header("content-type:text/xml; charset=UTF-8");

  9. Netty 系列(三)Netty 入门

    Netty 系列(三)Netty 入门 Netty 是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠性的网络服务器和客户端程序.更多请参考:Netty Github 和 Netty中文 ...

  10. CentOs7中的网卡配置工具

    CentOs7中的网卡配置工具 摘自:https://blog.51cto.com/13572810/2087991 misslaziness1人评论2715人阅读2018-03-17 22:09:1 ...