当前位置:网站首页>LeetCode - 460 LFU 缓存(设计 - 哈希表+双向链表 哈希表+平衡二叉树(TreeSet))*
LeetCode - 460 LFU 缓存(设计 - 哈希表+双向链表 哈希表+平衡二叉树(TreeSet))*
2022-07-03 09:20:00 【三岁就很萌@D】


哈希表 + 平衡二叉树(TreeSet)

class LFUCache {
class Node{
int key;//key
int val;//val
int freq;//使用频率
int t;//最后一次被使用的时间
public Node(int key,int val,int freq,int t){
this.key = key;
this.val = val;
this.freq = freq;
this.t = t;
}
}
class NodeComparator implements Comparator<Node>{
//当使用频率不一样时 按使用频率升序排序
public int compare(Node n1,Node n2){
if(n1.freq != n2.freq)
return n1.freq - n2.freq;
else//当使用频率一样的时候 按使用的时间升序排序
return n1.t - n2.t;
}
}
private Map<Integer,Node> map;
private TreeSet<Node> set;
//时间计数器 从0开始
private int t;
//LFU缓存的容量
private int capacity;
public LFUCache(int capacity) {
this.map = new HashMap<>();
this.set = new TreeSet<>(new NodeComparator());
this.t = 0;
this.capacity = capacity;
}
public int get(int key) {
//时间计数器加一
this.t += 1;
if(map.get(key) == null){
return -1;
}
else{
Node node = map.get(key);
set.remove(node);
//该key的使用频率加一
node.freq = node.freq + 1;
//更新key最后被使用的时间
node.t = this.t;
set.add(node);
map.put(key,node);
return node.val;
}
}
public void put(int key, int value){
if(this.capacity == 0)
return ;
this.t += 1;
//如果key本来就存在于map中
if(map.get(key)!=null){
Node node = map.get(key);
set.remove(node);
//更新val值
node.val = value;
//更新最后使用时间
node.t = this.t;
//使用频率加一
node.freq = node.freq + 1;
set.add(node);
map.put(key,node);
}else{
//如果LFU缓存中没有空间 弹出最近最久未使用的
if(set.size() >= this.capacity){
map.remove(set.first().key);
set.remove(set.first());
}
Node node = new Node(key,value,1,this.t);
map.put(key,node);
set.add(node);
}
}
}
/** * 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); */
哈希表 + 双向链表

class LFUCache {
class Node{
int key;//key
int val;//val
int freq;//key 使用频率
Node prev;//前驱指针
Node next;//后驱指针
public Node(int key,int val,int freq){
this.key = key;
this.val = val;
this.freq = freq;
}
}
class DoublyLinkedList{
//双向链表
Node head;//头指针
Node tail;//尾指针
int size;//双向链表中节点个数
public DoublyLinkedList(){
head = new Node(0,0,0);//头节点
tail = new Node(0,0,0);//尾节点
head.next = tail;
tail.prev = head;
size = 0;
}
public void addFirst(Node node){
Node headNext = head.next;
head.next = node;
node.prev = head;
node.next = headNext;
headNext.prev = node;
size += 1;
}
public void remove(Node node){
Node nodePrev = node.prev;
Node nodeNext = node.next;
nodePrev.next = nodeNext;
nodeNext.prev = nodePrev;
size -= 1;
}
public Node getHead(){
return head.next;
}
public Node getTail(){
return tail.prev;
}
}
// key, Node
private Map<Integer,Node> keyMap;
//每个频率 对应的节点放在双向链表中 双向链表按操作时间排序 越久没操作的节点在链表中的位置越靠后
private Map<Integer,DoublyLinkedList> freqMap;
//LFU缓存容量
private int capacity;
//最小操作频率
private int minFreq;
public LFUCache(int capacity) {
keyMap = new HashMap<>();
freqMap = new HashMap<>();
this.capacity = capacity;
minFreq = 0;
}
public int get(int key) {
if(this.capacity == 0)
return -1;
if(keyMap.get(key) == null){
return -1;
}
else{
Node node = keyMap.get(key);
DoublyLinkedList dl = freqMap.get(node.freq);
dl.remove(node);
if(dl.size == 0){
freqMap.remove(node.freq);
if(node.freq == minFreq)
minFreq += 1;
}
node.freq += 1;
if(freqMap.get(node.freq) == null)
freqMap.put(node.freq,new DoublyLinkedList());
freqMap.get(node.freq).addFirst(node);
keyMap.put(key,node);
return node.val;
}
}
public void put(int key, int value) {
if(this.capacity == 0)
return ;
if(keyMap.containsKey(key)){
Node node = keyMap.get(key);
DoublyLinkedList dl = freqMap.get(node.freq);
dl.remove(node);
if(dl.size == 0){
freqMap.remove(node.freq);
if(node.freq == minFreq)
minFreq += 1;
}
node.freq += 1;
node.val = value;
if(freqMap.get(node.freq) == null)
freqMap.put(node.freq,new DoublyLinkedList());
freqMap.get(node.freq).addFirst(node);
keyMap.put(key,node);
}
else{
if(keyMap.size() >= capacity){
Node node = freqMap.get(minFreq).getTail();
keyMap.remove(node.key);
freqMap.get(minFreq).remove(node);
if(freqMap.get(minFreq).size == 0)
freqMap.remove(minFreq);
}
Node newNode = new Node(key,value,1);
if(freqMap.get(newNode.freq) == null)
freqMap.put(newNode.freq,new DoublyLinkedList());
freqMap.get(newNode.freq).addFirst(newNode);
minFreq = 1;
keyMap.put(key,newNode);
}
}
}
/** * 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); */
边栏推荐
- Design of charging pile mqtt transplantation based on 4G EC20 module
- Programming ideas are more important than anything, not more than who can use several functions, but more than the understanding of the program
- Project cost management__ Cost management technology__ Article 7 completion performance index (tcpi)
- Adaptiveavgpool1d internal implementation
- Application of external interrupts
- Uniapp realizes global sharing of wechat applet and custom sharing button style
- Yocto Technology Sharing Phase 4: Custom add package support
- 编程思想比任何都重要,不是比谁多会用几个函数而是比程序的理解
- The new series of MCU also continues the two advantages of STM32 product family: low voltage and energy saving
- Simple use of MySQL (addition, deletion, modification and query)
猜你喜欢

Working mode of 80C51 Serial Port

要选择那种语言为单片机编写程序呢

內存數據庫究竟是如何發揮內存優勢的?

Open Euler Kernel Technology Sharing - Issue 1 - kdump Basic Principles, use and Case Introduction
![[untitled] proteus simulation of traffic lights based on 89C51 Single Chip Microcomputer](/img/90/4de927e797ec9c2bb70e507392bed0.jpg)
[untitled] proteus simulation of traffic lights based on 89C51 Single Chip Microcomputer

Which language should I choose to program for single chip microcomputer

Timer and counter of 51 single chip microcomputer

el-table X轴方向(横向)滚动条默认滑到右边

没有多少人能够最终把自己的兴趣带到大学毕业上

Embedded systems are inherently flawed. Compared with the Internet, there are so many holes that it is simply difficult to walk away from
随机推荐
Stm32 NVIC interrupt priority management
I didn't think so much when I was in the field of single chip microcomputer. I just wanted to earn money to support myself first
MySQL的简单使用(增删改查)
自動裝箱與拆箱了解嗎?原理是什麼?
4G module designed by charging pile obtains signal strength and quality
My notes on the development of intelligent charging pile (III): overview of the overall design of the system software
Idea remote breakpoint debugging jar package project
学历是一张通行证,门票,你有了它,可以踏入更高层次的环境里
自动装箱与拆箱了解吗?原理是什么?
My 4G smart charging pile gateway design and development related articles
使用sed替换文件夹下文件
编程思想比任何都重要,不是比谁多会用几个函数而是比程序的理解
Application of 51 single chip microcomputer timer
Project cost management__ Cost management technology__ Article 7 completion performance index (tcpi)
应用最广泛的8位单片机当然也是初学者们最容易上手学习的单片机
(1) What is a lambda expression
嵌入式本来就很坑,相对于互联网来说那个坑多得简直是难走
2020-08-23
Stm32-hal library learning, using cubemx to generate program framework
Serial port programming