LRU Cache
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.
分析:
超时版本,用list作底层数据结构:
class LRUCache{ private: list<pair<int,int>> cache; int capacity; int size; list<pair<int,int>>::iterator myfind(int key){ for(auto i = cache.begin(); i != cache.end(); i++) if(i->first == key) return i; return cache.end(); } public: LRUCache(int capacity) { this->capacity = capacity; size = 0; } int get(int key) { if(size == 0) return -1; list<pair<int,int>>::iterator p; if((p = myfind(key)) != cache.end()){ pair<int,int> tmp = *p; cache.erase(p); cache.push_front(tmp); return tmp.second; }else return -1; } void set(int key, int value) { list<pair<int,int>>::iterator p; if(size == 0 || (p = myfind(key)) == cache.end()){ if(size == capacity){ cache.pop_back(); size--; } cache.push_front(make_pair(key, value)); size++; }else{ p->second = value; cache.push_front(*p); cache.erase(p); } } };
上面的代码在查找时很费时,为了使减少查找时间,可以用unordered_map存储现有的key值和对应的list的迭代器,代码如下:
class LRUCache{ private: list<pair<int,int>> cache; unordered_map<int, list<pair<int,int>>::iterator> key_map; int capacity; int size; public: LRUCache(int capacity) { this->capacity = capacity; size = 0; } int get(int key) { if(size == 0) return -1; unordered_map<int, list<pair<int,int>>::iterator>::iterator p; if((p = key_map.find(key)) != key_map.end()){ pair<int,int> tmp = *(p->second); cache.erase(p->second); cache.push_front(tmp); key_map[key] = cache.begin(); return tmp.second; }else return -1; } void set(int key, int value) { unordered_map<int, list<pair<int,int>>::iterator>::iterator p = key_map.find(key); if(size == 0 || p == key_map.end()){ if(size == capacity){ key_map.erase(cache.back().first); cache.pop_back(); size--; } cache.push_front(make_pair(key, value)); size++; }else{ p->second->second = value; cache.push_front(*(p->second)); cache.erase(p->second); } key_map[key] = cache.begin(); } };