题目:
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.
题目来源:https://oj.leetcode.com/problems/lru-cache/
解题思路:如何构造一个结构,能够快速查看并且删除和插入节点。这里用到了两个结构,即用list来保存每次访问和插入的节点<key,value>,用map来保存<key,list<Node>::iterator>,这样根据键值key就能找到其在list中的位置,进行有效的插入和删除,或者修改。这个题在操作系统中有涉及,当时书上写了用下面的方法,觉得挺简单,就是再次碰到就给忘掉了,只记得还有一种解法用的是最小二叉堆。不过这个题貌似用二叉堆不好做。
#include<iostream>
#include<list>
#include<unordered_map>
using namespace std;
class LRUCache{
struct Node
{
int value;
int key;
Node(int _key=0,int _value=0):key(_key),value(_value){}
};
unordered_map<int,list<Node>::iterator> mp;
int capacity;
int size;
list<Node> li;
public:
LRUCache(int capacity)
{
this->capacity=capacity;
size=0;
}
int get(int key)
{
auto iter=mp.find(key);
if(iter==mp.end())
return -1;
else
{
li.splice(li.begin(),li,mp[key]);
mp[key]=li.begin();
return li.begin()->value;
}
}
void set(int key, int value)
{
if(mp.find(key)!=mp.end())
{
mp[key]->value=value;//修改为新的value值
li.splice(li.begin(),li,mp[key]);//把节点放到首部
mp[key]=li.begin();//修改对应的mp
return ;
}
if(size==capacity)
{
auto iter=li.back();
mp.erase(iter.key);
li.pop_back();
li.insert(li.begin(),Node(key,value));
mp[key]=li.begin();
}
else
{
li.insert(li.begin(),Node(key,value));
mp[key]=li.begin();
}
}
};
int main()
{
LRUCache lru(1);
lru.set(2,1);
cout<<lru.get(2)<<endl;
lru.set(3,2);
cout<<lru.get(2)<<endl;
cout<<lru.get(3)<<endl;
system("pause");
return 0;
}