题目:

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. mysql连接数据库存报下面错误:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

    输入 mysql -u root 登录 mysql 的时候出现以下错误: ERROR 2002 (HY000): Can't connect to local MySQL server through ...

  2. onsubmit return false仍提交表单

    博主之前遇到这样的问题,是因为代码有错,改正之后就正常了. 但今天确定代码没错,仍然return false提交表单. 总结网上各路大神的解释: 1.onsubmit的作用是防止form只有一个inp ...

  3. python数据类型内部结构解剖

    一.前言 我们知道,python是一种动态语言,可以将任何类型的数据赋给任何变量,譬如: # Python代码 x = 4 x = "four" 这里已经将 x 变量的内容由整型转 ...

  4. swift - 代码创建 pickerView 显示或隐藏横线

    import UIKit class VC1: UIViewController { fileprivate lazy var pickerV : UIPickerView = { let v = U ...

  5. PostgreSQL+pgpool-II复制方案

    目录 PostgreSQL+pgpool-II复制方案 1. Pgpool-II介绍 2. pgpool-II安装 2.1 安装pgpool-II yum源,并安装pgpool-II 2.2 添加Pg ...

  6. Codeforces 677C. Vanya and Label 位操作

    C. Vanya and Label time limit per test:1 second memory limit per test:256 megabytes input:standard i ...

  7. WCF数据契约代理和已知类型的使用

    using Bll; using System; using System.CodeDom; using System.Collections.Generic; using System.Collec ...

  8. kbmMWEncodeEscapes 中汉字编码的问题及解决办法

    kbmMWEncodeEscapes 是kbmmw 里面的一个函数,用来对URL 中的汉字进行编码,例如 http://127.0.0.1/getname?name=春节,由于'春节'是汉字,浏览器向 ...

  9. 2018.09.15点名器(简单dp)

    描述 Ssoier在紧张的学习中,杜老师每天给他们传授精妙的知识. 杜老师为了活跃气氛,设计了一个点名器,这个点名器包含一个长度为M的数组(下标1开始),每个元素是一个oier的名字,每次点名的时候, ...

  10. 2018.08.28 洛谷P4360 [CEOI2004]锯木厂选址(斜率优化dp)

    传送门 一道斜率优化dp入门题. 是这样的没错... 我们用dis[i]表示i到第三个锯木厂的距离,sum[i]表示前i棵树的总重量,w[i]为第i棵树的重量,于是发现如果令第一个锯木厂地址为i,第二 ...