146. LRU缓存机制
思路
一开始的思路是用map
来保存每个key
和pair<value,顺序>
,顺序是用1,2,3…来表示的,越后面越表示没被访问。每当执行get
和put
的时候,访问的那个pair
就移到1,它之前的页面就全往后移一位。这样也是能过简单的样例的,但是在最后几个样例会超时。因为它每次put
和get
都会把所有的map
遍历一遍,非常耗时。
所以就去看了题解,发现需要用到哈希表来解决搜索的问题,用双向列表来解决排列的问题。这方面详细的介绍就去看题解吧~
ac代码
class LRUCache {
public:
int capacity;
list<pair<int, int>> l;
unordered_map<int, list<pair<int, int>>::iterator> hash;
LRUCache(int capacity) {
this->capacity = capacity;
}
int get(int key) {
auto a = hash.find(key);
if(a == hash.end()) return -1;
l.push_front(make_pair(hash[key]->first, hash[key]->second));
l.erase(a->second);
hash[key] = l.begin();
return hash[key]->second;
}
void put(int key, int value) {
auto a = hash.find(key);
if(a != hash.end()){
l.push_front(make_pair(key, value));
l.erase(a->second);
hash[key] = l.begin();
return;
}
if(hash.size() == capacity){
hash.erase(l.rbegin()->first);
l.pop_back();
}
l.push_front(make_pair(key, value));
hash[key] = l.begin();
}
};
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache* obj = new LRUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/
超时代码
class LRUCache {
public:
int capacity;
map<int, pair<int, int>> m;
LRUCache(int capacity) {
this->capacity = capacity;
}
int get(int key) {
if(m.find(key) == m.end()) return -1;
for(auto& p: m){
if(p.second.second < m[key].second)
p.second.second ++;
}
m[key].second = 1;
return m[key].first;
}
void put(int key, int value) {
if(m.find(key) != m.end()){
for(auto& p: m){
if(p.second.second < m[key].second)
p.second.second ++;
}
m[key] = make_pair(value, 1);
return;
}
if(m.size() == capacity){
for(auto& p: m){
if(p.second.second == capacity){
m.erase(p.first);
break;
}
}
for(auto& p: m)
p.second.second ++;
m[key] = make_pair(value, 1);
}
else{
for(auto& p: m)
p.second.second ++;
m[key] = make_pair(value, 1);
}
}
};
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache* obj = new LRUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/