-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSolution460.java
More file actions
140 lines (124 loc) · 3.74 KB
/
Copy pathSolution460.java
File metadata and controls
140 lines (124 loc) · 3.74 KB
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import java.util.*;
class LFUCache {
// 双向链表结点
class DoubleListNode {
private int key;
private int value;
private int count;
private DoubleListNode prev;
private DoubleListNode next;
public DoubleListNode() {}
public DoubleListNode(int key, int value) {
this.key = key;
this.value = value;
this.count = 1;
}
}
// 双向链表
class DoubleLinkedList {
private DoubleListNode head; // 哨兵头节点
private DoubleListNode tail; // 哨兵尾节点
int size;
public DoubleLinkedList() {
this.head = new DoubleListNode();
this.tail = new DoubleListNode();
this.size = 0;
head.next = tail;
tail.prev = head;
}
public void addFirst(DoubleListNode node) {
node.prev = head;
node.next = head.next;
head.next.prev = node;
head.next = node;
size++;
}
public int removeLast() {
int res = tail.prev.key;
if (tail.prev != head) {
tail.prev = tail.prev.prev;
tail.prev.next = null;
tail.prev.next = tail;
size--;
}
return res;
}
public void remove(DoubleListNode node) {
node.prev.next = node.next;
node.next.prev = node.prev;
size--;
}
}
private Map<Integer, DoubleLinkedList> freMap;
private Map<Integer, DoubleListNode> map;
private int capacity;
private int minNum;
public LFUCache(int capacity) {
this.freMap = new HashMap<>();
this.map = new HashMap<>();
this.capacity = capacity;
this.minNum = 1;
}
public int get(int key) {
if (!map.containsKey(key)) {
return -1;
}
DoubleListNode temp = map.get(key);
// 从当前链移除temp结点
freMap.get(temp.count).remove(temp);
// 更新最小次数
if (freMap.get(temp.count).size == 0) {
if (minNum == temp.count) {
minNum++;
}
}
// 将temp结点放到次数为cnt + 1 的链表中
temp.count++;
if (!freMap.containsKey(temp.count)) {
freMap.put(temp.count, new DoubleLinkedList());
}
freMap.get(temp.count).addFirst(temp);
return temp.value;
}
public void put(int key, int value) {
// 特例
if (capacity == 0) {
return;
}
// 缓存已满
if (map.size() >= capacity && !map.containsKey(key)) {
int x = freMap.get(minNum).removeLast();
map.remove(x);
}
// 缓存未满
DoubleListNode temp = null;
if (map.containsKey(key)) {
temp = map.get(key);
// 从当前链移除temp结点
freMap.get(temp.count).remove(temp);
// 更新最小次数
if (freMap.get(temp.count).size == 0) {
if (minNum == temp.count) {
minNum++;
}
}
temp.value = value;
temp.count++;
} else {
temp = new DoubleListNode(key, value);
minNum = 1;
}
// 将temp放到次数为cnt + 1 的链表中
if (!freMap.containsKey(temp.count)) {
freMap.put(temp.count, new DoubleLinkedList());
}
freMap.get(temp.count).addFirst(temp);
map.put(key, temp);
}
}
/**
* Your LFUCache object will be instantiated and called as such:
* LFUCache obj = new LFUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/