class LinkedHashSet {
constructor() {
this.set = new Set();
this.head = null;
this.tail = null;
}
findFirstElement() {
return this.head;
}
size() {
let size = 0
let current = this.head
while (current !== null) {
size+=1
current = current.next;
}
return size
}
add(element) {
if (!this.set.has(element)) {
const entry = { element, prev: null, next: null };
if (this.head === null) {
this.head = entry;
this.tail = entry;
} else {
this.tail.next = entry;
entry.prev = this.tail;
this.tail = entry;
}
this.set.add(element);
}
}
delete(element) {
if (this.set.has(element)) {
const entry = this.findEntry(element);
if (entry.prev) {
entry.prev.next = entry.next;
} else {
this.head = entry.next;
}
if (entry.next) {
entry.next.prev = entry.prev;
} else {
this.tail = entry.prev;
}
this.set.delete(element);
}
}
has(element) {
return this.set.has(element);
}
forEach(callback) {
let current = this.head;
while (current !== null) {
callback(current.element);
current = current.next;
}
}
findEntry(element) {
let current = this.head;
while (current !== null) {
if (current.element === element) {
return current;
}
current = current.next;
}
return null;
}
toArray() {
const result = [];
this.forEach((element) => {
result.push(element);
});
return result;
}
}
const set = new LinkedHashSet();
let LFUCache = function (capacity) {
this.keyToVal = new Map()
this.keyToFreq = new Map()
this.freqToKeys = new Map()
this.cap = capacity
this.minFreq = 0
}
LFUCache.prototype.increaseFreq = function(key) {
console.log('------------增加Freq开始--------------')
console.log(`增加key:${key}的freq`)
let freq = this.keyToFreq.get(key)
console.log(`当前key:${key}的freq:${freq}`)
this.keyToFreq.set(key, freq+1)
console.log(`设置keyToFreq中key:${key}对应的freq+1`, freq + 1)
console.log(`keyToFreq:`, this.keyToFreq)
console.log(`开始删除freqToKeys中freq:${freq}对应的列表中的key:${key}`)
let flag = this.freqToKeys.has(freq)
console.log('flag:', flag)
if(flag) {
console.log('flag:true中的freqToKeys', this.freqToKeys)
this.freqToKeys.get(freq).delete(key)
}
console.log(`freqToKeys中的当前key:${key}删除结束`, this.freqToKeys)
if(this.freqToKeys.get(freq + 1)) {
this.freqToKeys.get(freq + 1).add(key)
console.log(`如果当前freqToKeys有freq+1:${freq+1}的键, 直接将key放到数组`)
} else {
let a = new LinkedHashSet();
a.add(key)
console.log('aaa', a)
this.freqToKeys.set(freq + 1, a)
console.log(`如果当前freqToKeys没有freq+1:${freq+1}的键, 则创建一个,并且直接将key放到数组`)
}
console.log('当前freqToKeys结构:', this.freqToKeys)
console.log(`this.freqToKeys.get(freq).size, freq:${freq}`, this.freqToKeys.get(freq).size())
if(this.freqToKeys.get(freq).size()===0) {
console.log(`this.freqToKeys`, this.freqToKeys)
console.log('当前freq对应的列表空了,移除这个freq')
this.freqToKeys.delete(freq)
if(freq==this.minFreq) {
this.minFreq++;
}
}
console.log('最终的freqToKeys', this.freqToKeys)
}
LFUCache.prototype.removeMinFreqKey = function() {
console.log('------------容量满了移除最小频率的key开始------------')
console.log('当前freqToKeys-1-1-1-1', this.freqToKeys)
let keyList = this.freqToKeys.get(this.minFreq)
console.log('当前keyList: ', keyList)
let deletedElement = keyList.findFirstElement()
let deletedKey = deletedElement.element
console.log('deletedElement:', deletedElement)
keyList.delete(deletedKey)
if(keyList.size===0) {
this.freqToKeys.delete(this.minFreq)
}
console.log('设置freqToKeys开始00000', this.freqToKeys)
this.keyToVal.delete(deletedKey)
this.keyToFreq.delete(deletedKey)
console.log('设置freqToKeys开始11111', this.freqToKeys)
}
LFUCache.prototype.get = function (key) {
if (!this.keyToFreq.has(key)) {
return -1;
}
this.increaseFreq(key)
console.log(`取出KeyToVal中key:${key}的值`, this.keyToVal.get(key))
return this.keyToVal.get(key)
}
LFUCache.prototype.put = function (key, val) {
console.log(`-------------put开始-------------,key:${key}, val:${val}`)
console.log('this.freqToKeys', this.freqToKeys)
if(this.cap <= 0) return;
if(this.keyToVal.has(key)) {
this.keyToVal.set(key, val)
this.increaseFreq(key);
return
}
if(this.cap<=this.keyToVal.size) {
this.removeMinFreqKey()
}
this.keyToVal.set(key, val)
console.log('设置keyToVal', this.keyToVal)
this.keyToFreq.set(key, 1)
console.log(`设置KeyToFreq为1`, this.keyToFreq)
console.log('设置freqToKeys开始22222', this.freqToKeys)
if(this.freqToKeys.get(1)) {
console.log('1次push')
this.freqToKeys.get(1).add(key)
} else {
console.log('没有push')
this.freqToKeys.set(1, new LinkedHashSet())
this.freqToKeys.get(1).add(key)
}
console.log('%设置freqToKeys的HashSet%', this.freqToKeys)
this.minFreq = 1;
console.log('设置minFreq为1')
}
let lfu = new LFUCache(2);
lfu.put(1, 3);
lfu.put(2, 4);
console.log(lfu.get(1));
console.log('lfu.put(3, 3)----->')
lfu.put(3, 3);
console.log('lfu.get(2)', lfu.get(2));
console.log('lfu.get(3)', lfu.get(3));
lfu.put(4, 4);
console.log(`lfu.get(1)`, lfu.get(1));
console.log(`lfu.get(3)`, lfu.get(3));
console.log(`lfu.get(4)`, lfu.get(4));