题目大意:
就是实现内存管理中的LRU(Least Recently Used)内存管理算法
内存管理算法的话,LRU和LFU不同,LRU是移除最久没有使用的页
而LFU是移除最近使用次数最少的页
大致思路:
这个问题的话,表示刚好复习了一下内存管理...
首先由于每个内存块在被使用时,会导致一个内存块最近被使用,而其他的块的相对位置不变,考虑用链表来表示他们,这里使用双向链表,链表从头节点往结尾,越是最近使用,也就是说尾节点是最近访问的,当容量满的时候,删除头节点,腾出空间,插入和移动节点的复杂度是O(1)
当set的时候由于需要查找key对应的value, 考虑用map来进行维护,用map<int, listNode* > 来在O(logn)的时间复杂度内找到对应的节点位置
那么查找节点是否在内存池中的复杂度也就是O(logn),整体的单词操作的时间复杂度是O(logn)
代码如下:
Result : Accepted Time : 96 ms
/*
* Author: Gatevin
* Created Time: 2016/3/7 11:06:11
* File Name: test.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
typedef long long lint;
class LRUCache{
private:
struct listNode{
listNode* next;
listNode* prev;
int key;
int value;
listNode(){
next = NULL;
prev = NULL;
key = -1;
value = 0;
}
};
int lruCapacity;
int curCapacityUsed;
listNode* p_Head;
listNode* p_Tail;
map<int, listNode*> M;//查找某个key值有没有出现过
public:
LRUCache(int capacity) {
if(capacity <= 0) puts("Error, capacity should be at least 1");
p_Head = NULL;
p_Tail = NULL;
lruCapacity = capacity;
curCapacityUsed = 0;
M.clear();
}
void moveToTail(listNode* now){
if(now->next == NULL)//本来就是末尾节点
return;
else{
if(now->prev == NULL){//头节点
p_Head->next->prev = NULL;
p_Head = p_Head->next;
now->next = NULL;
now->prev = p_Tail;
p_Tail->next = now;
p_Tail = now;
return;
}else{//中间节点
now->prev->next = now->next;
now->next->prev = now->prev;
p_Tail->next = now;
now->prev = p_Tail;
now->next = NULL;
p_Tail = now;
return;
}
}
}
int get(int key) {
map<int, listNode*> :: iterator it = M.find(key);
if(it == M.end())//Not found
return -1;
else{//查找到了,将这个结点移动到链表最后面
moveToTail(it->second);
return it->second->value;
}
}
void set(int key, int value) {
map<int, listNode*> :: iterator it = M.find(key);
if(it == M.end()){//Not found
if(p_Head == NULL){//链表为空
p_Head = new listNode();
p_Head->key = key;
p_Head->value = value;
p_Tail = p_Head;
M[key] = p_Head;
curCapacityUsed++;
return;
}else{//链表不为空,添加新节点到链表末尾
if(curCapacityUsed == lruCapacity){//已满,需要删除头节点再插入
if(p_Head->next == NULL){
M.erase(p_Head->key);
delete p_Head;
p_Head = NULL;
p_Tail = NULL;
curCapacityUsed--;
}else{
M.erase(p_Head->key);
p_Head = p_Head->next;
delete p_Head->prev;
p_Head->prev = NULL;
curCapacityUsed--;
}
}
//接下来在末尾插入新节点
listNode* newTail = new listNode();
newTail->value = value;
newTail->key = key;
if(p_Tail == NULL){
p_Head = newTail;
p_Tail = p_Head;
}else{
p_Tail->next = newTail;
newTail->prev = p_Tail;
p_Tail = newTail;
}
M[key] = p_Tail;
curCapacityUsed++;
}
}else{
moveToTail(it->second);
it->second->value = value;
return;
}
}
};