LRUCache详解

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
put(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.

Follow up:
Could you do both operations in O(1) time complexity?

Example:

设计一个简单版的最近使用缓存模型。其中,缓存空间有容量限制,时间复杂度要求是o(1).

“最近使用”指的是最近被访问过。

思路:对以上cache的操作有:查找(get),添加(put),替换(put)。因有容量限制,还需要有删除,每次当cache中的容量满了的时候,将最久未使用的节点删除。

为快速添加和删除,我们可以用双向链表来设计cache,链表中从头到尾的数据顺序依次是:

(最近访问)--> ... --> (最旧访问)

1.添加节点:新节点插入到表头即可,时间复杂度为O(1);

2.删除节点:删除链表的末尾节点,时间复杂度为O(1);

3.查找节点:按顺序对链表进行遍历,时间复杂度为O(n);

当节点被查询到时,将节点移动到链表头部。

4.替换节点:查找到后替换节点,将节点移动到链表头部,时间复杂度为O(n).

因此,为了保证在查找和替换节点的时候,由时间复杂度O(n)变为O(1),可以考虑在数据结构中加入hash。

c++代码示例:

#include<list>
#include<unordered_map>

struct CacheNode
{
	int key;
	int value;
	CacheNode(int k, int v){
		key = k;
		value = v;
	}
};

class LRUCache{
public:
	LRUCache(int capacity){

	}

	int get(int key){
		if(cacheMap.find(key) == cacheMap.end()) 
			return -1;
		else{
			//把当前访问的节点移到链表头部,并且更新map中该节点的地址
			cacheList.splice(cacheList.begin(), cacheList, cacheMap[key]);
			cacheMap[key] = cacheList.begin();
			return cacheMap[key]->value;
		}
	}

	void put(int key, int value){
		if(cacheMap.find(key) == cacheMap.end())
		{
			if(cacheList.size() == size){
				//删除链表尾部节点(最少访问的节点)
				cacheMap.erase(cacheList.back().key);
				cacheList.pop_back();
			}
			//插入新节点到链表头部,并且更新map中增加该节点
			cacheList.push_front(CacheNode(key, value));
			cacheMap[key] = cacheList.begin();
		}
		else{
			//更新节点到值,把当前访问的节点移到链表头部,并且更新map中该节点的地址
			cacheMap[key]->value = value;
			cacheList.splice(cacheList.begin(), cacheList, cacheMap[key]);
			cacheMap[key] = cacheList.begin();
		}
	}
private:
	list<CacheNode> cacheList;
	unordered_map<int, list<CacheNode>::iterator> cacheMap;
	int size;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值