Neo's Blog

不抽象就无法深入思考
不还原就看不到本来面目!

0%

链表系列-LRU缓存

什么是LRU缓存,怎么设计的LRU缓存。
时间复杂度:$O(1)$

  1. Hash + 双向链表
  2. 哨兵节点来简化判断
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

struct ListNode {
int val;
ListNode* next;
ListNode* pre;
}


class LRUCache {
private:
unordered_map<int, ListNode*> hash;
ListNode* head;
ListNode* tail;
int n;

LRUCache(int nn) {
n = nn;
head = new ListNode();
tail = new ListNode();
head->next = tail;
tail->pre = head;
}

void put(int k, int v) {
ListNode* r = get2(k);
if (r != NULL) return;

ListNode* node = NULL;
if (hash.size() > n) {
//链表上移除
auto node = tail->pre;
node->next->pre = node->pre;
node->pre->next = node->next;
//hash移除
hash.erase(node->k);
}
else {
node = new ListNode();
}

node.val = v;
//将node放在头部
node->next = head->next;
node->pre = head;

head->next->pre = node;
head->next = node;

hash[k] = node;

}

ListNode* get2(int k) {
auto it = hash.find(k);
if it == hash.end() {
return NULL;
}

auto node = *it;

//移除
node->next->pre = node->pre;
node->pre->next = node->next;

node->next = head->next;
node->pre = head;

head->next->pre = node;
head->next = node;
}

int get(int k) {
ListNode* r = get2(k);
if (r == NULL) return -1;
else r->val;
}
};

你的支持是我坚持的最大动力!