这道题我解法的put函数严格意义上讲不是O(1),不如力扣官方的题解。
我使用了哈希表存储值,这样每次get就可以O(1)了。但是put不太好优化成O(1),我使用了一个队列和一个哈希表来实现它。通过记录一个数据的使用次数存在哈希表,数据存储顺序放在queue,来实现这个put。但是如果capacity满了,每次put会弹出不定数的数据。虽然每次的次数基本会很少.但是在极端情况下会是O(n-capacity)。
我很喜欢官方题解的方式,他使用了一个哈希表和一个双向链表,并将它们组合成一个新的数据结构,哈希表key为数据的索引,value是链表结点的指针,链表中存放数据。通过指针,将两个容器连接起来。get可以利用哈希表的性质实现快速查询,put可以利用双端链表的特性,可以灵活的将对应结点移到队首,将队尾的删除。
我的方法:
cpp
class LRUCache {
public:
unordered_map<int,int> cache;
unordered_map<int,int> update;
queue<int> q;
int cap=0;
int n=0;
LRUCache(int capacity) {
cap=capacity;
}
int get(int key) {
if(cache.find(key)!=cache.end())
{
if(update.find(key)!=cache.end()) update[key]++;
else update[key]=1;
q.push(key);
return cache[key];
}
return -1;
}
void put(int key, int value) {
if(cache.find(key)!=cache.end())
{
cache[key]=value;
if(update.find(key)!=cache.end()) update[key]++;
else update[key]=1;
q.push(key);
}
else if(++n<=cap)
{
cache[key]=value;
if(update.find(key)!=cache.end()) update[key]++;
else update[key]=1;
q.push(key);
}
else
{
n--;
cache[key]=value;
if(update.find(key)!=cache.end()) update[key]++;
else update[key]=1;
q.push(key);
while(1)
{
int t=q.front();
q.pop();
if(update[t]<=1)
{
update[t]--;
cache.erase(t);
return;
}
update[t]--;
}
}
}
};