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);
*/