-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathBM101.java
More file actions
113 lines (108 loc) · 3.61 KB
/
BM101.java
File metadata and controls
113 lines (108 loc) · 3.61 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
package NiukeTOP101;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
public class BM101 {
// 设置节点结构
static class Node{
int freq;
int key;
int val;
public Node(int freq, int key, int val){
this.freq = freq;
this.key = key;
this.val = val;
}
}
// 频率到双向链表的哈希表
private Map<Integer, LinkedList<Node>> freq_mp = new HashMap<>();
// key到节点的哈希表
private Map<Integer, Node> mp = new HashMap<>();
// 记录缓存剩余容量
private int size = 0;
// 记录当前最小频次
private int min_freq = 0;
public int[] LFU (int[][] operators, int k) {
//构建初始化连接
//链表剩余大小
this.size = k;
//获取操作数
int len = (int) Arrays.stream(operators).filter(x -> x[0] == 2).count();
int[] res = new int[len];
//遍历所有操作
for(int i = 0, j = 0; i < operators.length; i++){
if(operators[i][0] == 1)
//set操作
set(operators[i][1], operators[i][2]);
else
//get操作
res[j++] = get(operators[i][1]);
}
return res;
}
// 调用函数时更新频率或者val值
private void update(Node node, int key, int val){
// 找到频率
int freq = node.freq;
// 原频率中删除该节点
freq_mp.get(freq).remove(node);
// 哈希表中该频率已无节点,直接删除
if(freq_mp.get(freq).isEmpty()){
freq_mp.remove(freq);
// 若当前频率为最小,最小频率加1
if(min_freq == freq){
min_freq ++;
}
}
if (!freq_mp.containsKey(freq + 1)){
freq_mp.put(freq + 1, new LinkedList<>());
}
// 插入频率加一的双向链表表头,链表中对应:freq key value
freq_mp.get(freq + 1).addFirst(new Node(freq + 1, key, val));
mp.put(key, freq_mp.get(freq + 1).getFirst());
}
// set操作函数
private void set(int key, int value){
// 在哈希表中找到key值
if(mp.containsKey(key)){
// 若是哈希表中有,则更新值和频率
update(mp.get(key), key, value);
}else{
// 哈希表中没有,即链表中没有
if(size == 0){
// 满容量取频率最低且最早的删除
int oldKey = freq_mp.get(min_freq).getLast().key;
// 频率哈希表的链表中删除
freq_mp.get(min_freq).removeLast();
if(freq_mp.get(min_freq).isEmpty()){
freq_mp.remove(min_freq);
}
mp.remove(oldKey);
}else{
size--;
}
// 最小频率置为1
min_freq = 1;
// 在频率为一的双向链表表头插入该建
if(!freq_mp.containsKey(1)){
freq_mp.put(1, new LinkedList<>());
}
freq_mp.get(1).addFirst(new Node(1, key, value));
// 哈希表key值指向链表中的该位置
mp.put(key, freq_mp.get(1).getFirst());
}
}
private int get(int key) {
int res = -1;
// 查找哈希表
if(mp.containsKey(key)){
Node node = mp.get(key);
// 根据哈希表直接获取值
res = node.val;
// 更新频率
update(node, key, res);
}
return res;
}
}