LRU
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.
The cache is initialized with a positive capacity.
Follow up:
Could you do both operations in O(1) time complexity?
Example:
LRUCache cache = new LRUCache( 2 /* capacity */ );
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // returns 1
cache.put(3, 3); // evicts key 2
cache.get(2); // returns -1 (not found)
cache.put(4, 4); // evicts key 1
cache.get(1); // returns -1 (not found)
cache.get(3); // returns 3
cache.get(4); // returns 4
Solution:
#include <vector>
#include <list>
#include <string>
#include <map>
#include <iostream>
#include <iomanip>
using namespace std;
struct cacheNode {
int key;
string value;
cacheNode(int k, string v):key(k), value(v) {}
};
class LRUCache {
public:
int capacity;
list<cacheNode> cacheList;
map<int, list<cacheNode>::iterator> cacheMap;
LRUCache(int size):capacity(size) {}
string get(int key) {
if(capacity <= 0) return "";
if(cacheMap.find(key) == cacheMap.end()) return "";
string value = cacheMap[key]->value;
cacheList.splice(cacheList.begin(), cacheList, cacheMap[key]);
cacheMap[key] = cacheList.begin();
return value;
}
void set(int key, string value) {
if(cacheMap.find(key) != cacheMap.end()) {
cacheMap.find(key)->second->value = value;
cacheList.splice(cacheList.begin(), cacheList, cacheMap[key]);
cacheMap[key] = cacheList.begin();
} else {
if(capacity == cacheList.size()) {
cacheMap.erase(cacheList.back().key);
cacheList.pop_back();
}
cacheList.push_front(cacheNode(key, value));
cacheMap[key] = cacheList.begin();
}
}
void show() {
if(capacity <= 0) return;
list<cacheNode>::iterator iter = cacheList.begin();
int i = 0;
while(iter != cacheList.end()) {
cout<< setw(2) << ++i << ": cacheNode(" << setw(2) << iter->key << ") = " << iter->value << endl;;
iter++;
}
cout <<endl;
}
};
int main() {
LRUCache *lru = new LRUCache(5);
lru->set(1, "1");
lru->set(2, "2");
lru->set(5, "3");
lru->set(6, "4");
lru->set(7, "5");
lru->set(10, "6");
lru->set(14, "7");
lru->set(12, "8");
lru->show();
lru->get(7);
lru->show();
return 1;
}