1、算法思路:
put操作思路:
用一个双向链表和一个哈希表;
每添加一个(key, value),先判断是否在哈希表中存在,如果存在,那么删除哈希表中的键值对和双向链表中的该元素;
再往双向链表头部增加添加的(key, value)和哈希表中增加(key,value);
最后判断是否超过capacity,若超过则弹出链表尾部元素和删除哈希表中该键值对。
优化:
哈希表中保存<int, list<in, int>::iterator>,这样可以再O(1)时间找到双向链表key对应的节点。
2、list和unordered_map常用方法:
unordered_map<int, int>mp;
mp.erase(key):通过key删除元素
mp.size():mp元素个数
list.size():元素个数
list.front():第一个元素
list.back():最后一个元素
list.push_front():增加一个元素到链表头部
list.pop_front()
list.push_back()
lis.pop_back():删除最末元素
list.erase(it):it为迭代器
注意:list没有find函数
3、代码:
#pragma once
#include<list>
#include<unordered_map>
using namespace std;
class LRUCache
{
public:
LRUCache();
~LRUCache();
LRUCache(int capacity) {
this->capacity = capacity;
}
int get(int key) {
if (mp.find(key) != mp.end())
{
put(key, mp[key]->second);
return mp[key]->second;
}
else
{
return -1;
}
}
void put(int key, int value) {
if (mp.find(key) != mp.end()) //说明原来中有键key,删除双向链表中的key-val
{
list1.erase(mp[key]);
//for (auto it = list1.begin(); it != list1.end(); it++)
//{
// if ((*it).first == key)
// {
// list1.erase(it);
// break;
// }
//}
}
list1.push_front(make_pair(key, value)); //添加元素到链表头
mp[key] = list1.begin();//注意
if(list1.size() > capacity)
{
mp.erase(list1.back().first);
list1.pop_back();
}
}
private:
int capacity;
list<pair<int, int>>list1;
unordered_map<int, list<pair<int, int>>::iterator>mp; //注意
};