1.手动实现双向链表class LRUCache {
public:
struct Node{
int key,val;
Node*left,*right;
Node(int _key,int _val):key(_key),val(_val),left(NULL),right(NULL){}
};
Node *L,*R;
unordered_map<int,Node*> map ;
int n;
int size ;
void remove(Node *p){
p->left->right = p->right;
p->right->left = p->left ;
}
void insertAtLeft(Node *p){
p->right = L->right;
p->left = L ;
L->right->left = p;
L->right = p;
}
LRUCache(int capacity) {
size = capacity ;
n = 0;
L = new Node(-1,-1);
R = new Node(-1,-1);
L->right = R ;
R->left = L ;
}
int get(int key) {
if(map.count(key)==0)
return -1;
int val = map[key]->val;
remove(map[key]);
Node *newNode = new Node(key,val);
map[key] = newNode ;
insertAtLeft(newNode);
return val;
}
void put(int key, int value) {
if(get(key)!=-1){
map[key]->val = value;
}
else{
Node *newNode = new Node(key,value);
if(n==size){
map.erase(R->left->key);
remove(R->left);
insertAtLeft(newNode);
}else{
insertAtLeft(newNode);
n++ ;
}
map[key]=newNode;
}
}
};
2.使用STL容器list(省去很多麻烦...)list的常见方法: - begin(): 返回第一个元素的迭代器
- end(): 最后一个元素的下一个位置的迭代器
- front(): 第一个元素的引用
- back(): 最后一个元素的引用
- emplace_front(), emplace_back() : 头部,尾部生成一个元素,比push_back效率高
- push_back(), pop_back(): 尾部插入、删除一个元素
- splice(): 将一个 list 容器中的元素插入到另一个容器的指定位置
class LRUCache {
private:
int cap = 0 ;
list<pair<int,int>> li;
unordered_map<int,list<pair<int,int>>::iterator> mp;
public:
LRUCache(int capacity) {
cap = capacity ;
}
int get(int key) {
if(mp.find(key)==mp.end())
return -1;
li.splice(li.begin(),li,mp[key]);
return li.begin()->second;
}
void put(int key, int value) {
if(get(key)!=-1)
li.begin()->second = value ;
else{
if(li.size()==cap){
int delKey = li.back().first;
li.pop_back();
mp.erase(delKey);
}
li.emplace_front(key,value);
mp[key]=li.begin();
}
}
};
|