146. LRU Cache
Medium
3402127FavoriteShare
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
Accepted
335,694
Submissions
1,250,622
写错了很多次,主要是迭代器这块有些知识没有弄清。
#include <iostream>
#include <bits/stdc++.h>
#include <list>
#include <stdlib.h>
using namespace std;
class LRUCache {
public:
LRUCache(int capacity) {
this->capacity = capacity;
}
void print_list(){
list<c_cache*>::iterator it_start = m_list.begin();
while(it_start!=m_list.end()){
c_cache* m_c = (*it_start);
cout<<"("<<m_c->m_key<<","<<m_c->m_value<<")"<<endl;
it_start++;
}
}
void print_map(){
unordered_map<int,list<c_cache*>::iterator>::iterator it_unorder;
it_unorder = m_cache.begin();
while(it_unorder != m_cache.end()){
auto it = it_unorder->second;
c_cache *m_map_v = (*it);
cout<<"key:"<<it_unorder->first;
cout<<"value:"<<"("<<m_map_v->m_key<<","<<m_map_v->m_value<<")"<<endl;
it_unorder++;
}
}
int get(int key) {
auto it = m_cache.find(key);
if(it==m_cache.end()){
cout<<"return -1"<<endl;
return -1;
}
cout<<"get in or not "<<endl;
if(m_cache.count(key)!=0){
auto it_get = m_cache[key];
// 1. 需要将哈希表的值重新指向,erase之后迭代器失效,remove方法也是一样
m_list.push_back(*it_get);
int ret_value = (*it_get)->m_value;
m_list.erase(it_get);
//重新指向
m_cache[key] = --m_list.end();
//2.m_list.splice(m_list.end(),m_list,it_get);
cout<<"return "<<ret_value<<endl;
return ret_value;
}else{
cout<<"return -1"<<endl;
return -1;
}
}
void put(int key, int value) {
auto it = m_cache.find(key);
if(it!=m_cache.end())
m_list.erase(it->second);
c_cache* m_node = new c_cache();
m_node->m_key = key;
m_node->m_value = value;
m_list.push_back(m_node);
m_cache[key]=--m_list.end(); //end()指向的不是最后一个元素,没有值
if(m_list.size()>capacity){
auto m_begin = m_list.begin();
c_cache *b_node = (*m_begin);
m_list.pop_front();
m_cache.erase(b_node->m_key);
}
}
void put_x(int key, int value) {
auto it = m_cache.find(key);
if(it!=m_cache.end())
m_list.erase(it->second);
c_cache* m_node = new c_cache();
m_node->m_key = key;
m_node->m_value = value;
m_list.push_front(m_node);
m_cache[key] = m_list.begin();
if(m_list.size()>capacity){
auto r_it = m_list.rbegin();
c_cache *r_node = (*r_it);
m_list.pop_back();
m_cache.erase(r_node->m_key);
}
}
private:
typedef struct m_un{
int m_key;
int m_value;
}c_cache;
list<c_cache *> m_list;
unordered_map<int, list<c_cache*>::iterator> m_cache;
int capacity = 0;
};
// cout<<"head->key = "<<head->m_key<<endl;
// cout<<"head->value = "<<head->m_value<<endl;
/**
* 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);
*/
/*
* new 2 new 3 capacity
* 1 put(1,1)
* 1 2 put(2,2)
* 2 1 get(1) return 1
* 1 3 put(3,3)
* 1 3 get(2) return -1
* 3 4 put(4,4)
* 3 4 get(1) return -1
* 4 3 get(3) return 3
* 3 4 get(4) return 4
*
*/
/* (2,1)
* (2,1) (1,1)
* (1,1) (2,1) return 1
* (2,1) (4,1)
* (2,1) (4,1) retunr -1
* (4,1) (2,1) return 1
*/
int main(){
LRUCache *cache = new LRUCache(2);
// cache->put(1, 1);
// cache->put(2, 2);
// cache->get(1); // returns 1
// cache->put(3, 3); // evicts key 2
// cache->get(2); // return -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
cache->put(2, 1);
cache->put(1, 1);
cache->get(2);
cache->put(4,1);
cache->get(1);
cache->get(2);
cout<<"print-----------------------------"<<endl;
cache->print_list();
cache->print_map();
system("pause");
return 0;
}