0%

146. LRU Cache

146. LRU Cache

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
class LRUCache {
public:
LRUCache(int capacity): capacity(capacity), head(new Node()), tail(new Node()) {
head->post = tail;
head->prev = nullptr;
tail->prev = head;
tail->post = nullptr;
}

int get(int key) {
if(cache.find(key) != cache.end())
{
moveNodeToHead(cache[key]);
return cache[key]->val;
}
else
return -1;
}

void put(int key, int value) {
if(cache.find(key) == cache.end())
{
if(cache.size() > capacity - 1)
cache.erase(removeTailNode());
Node* node = new Node(key, value);
addNodeToHead(node);
cache[key] = node;
}else
{
auto node = cache[key];
if(node->val != value)
node->val = value;
moveNodeToHead(node);
}
}
private:
struct Node {
int key;
int val;
Node* prev;
Node* post;
Node() = default;
Node(int key, int val): key(key), val(val) {}
};
void removeNode(Node* node)
{
node->prev->post = node->post;
node->post->prev = node->prev;
}
void addNodeToHead(Node* node)
{
node->prev = head;
node->post = head->post;
head->post = node;
node->post->prev = node;
}
void moveNodeToHead(Node* node)
{
removeNode(node);
addNodeToHead(node);
}
int removeTailNode()
{
auto node = tail->prev;
tail->prev = node->prev;
tail->prev->post = tail;
auto key = node->key;
delete node;
return key;
}
Node* head;
Node* tail;
int capacity;
unordered_map<int, Node*> cache;
};

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

使用doubleLinkedList是因为在删除时候需要操作前面的元素,因此DoublelinkedList可以实现O(1)的删除操作,而SingleLinkedList就需要O(n)
总体思路是访问过的移动到第一位,而最少访问的放在最后,如果新进来的时候缓存满了,那么就释放掉最后一位。