I'm getting a runtime error on LeetCode, but this works fine on my Linux system in 0.046 user time for largest testcase. The output matches exactly the expected output on LeetCode. My solution uses a hashmap and a doubly linked list. The hashmap stores an iterator to the linked list node (in addition to the key->value pair) so that the list can be updated O(1) instead of O(n). Got it to work for several testcases, but I get a runtime error on testcase with cache size 512 and 2019 instructions.
class LRUCache {
public:
LRUCache(int _capacity) { capacity = _capacity; }
int get(int key) {
if(hmap.find(key) == hmap.end()) return -1;
addq(key);
return hmap[key].first;
}
void put(int key, int value) {
list<int>::iterator ptr = addq(key);
hmap[key] = make_pair(value, ptr);
}
private:
list<int> q;
unordered_map<int, pair<int,list<int>::iterator>> hmap;
int capacity;
list<int>::iterator addq(int key) {
if(hmap.find(key) == hmap.end()) {
if(q.size() == capacity) {
int to_pop = q.back();
hmap.erase(to_pop);
q.pop_back();
}
}
else q.erase(hmap[key].second);
return q.insert(q.begin(), key);
}
};
There is a problem with your get (int key)
function. When you access the cache you have to invalidate the entry and update your iterators. You do that with your addq
function but never update the corresponding entry in your hmap
. Therefore a runtime error occurs because you then access an iterator which has already been invalidated by your addq
function.
Looking at the following snippet:
if(hmap.find(key) == hmap.end()) return -1;
addq(key);
return hmap[key].first;
The addq
returns an iterator, but you never update the iterator in your map, so this should be :
hmap[key].second = addq(key);