当前位置:网站首页>LeetCode--单链表--146.LRU缓存
LeetCode--单链表--146.LRU缓存
2022-07-29 20:17:00 【aMythhhhh】
146.LRU缓存()
LRU原理,利用双向链表加hashMap实现
class LRUCache {
private HashMap<Integer,Node>map;
private DoubleList cache;
private int capacity;
public LRUCache(int capacity) {
this.capacity = capacity;
map = new HashMap<>();
cache = new DoubleList();
}
public int get(int key) {
if(!map.containsKey(key)){
return -1;
}
makeRecently(key);
return map.get(key).val;
}
public void put(int key, int value) {
if (map.containsKey(key)) {
// 删除旧的数据
deleteKey(key);
// 新插入的数据为最近使用的数据
addRecently(key, value);
return;
}
if (capacity == cache.size()) {
// 删除最久未使用的元素
removeLeastRecently();
}
// 添加为最近使用的元素
addRecently(key, value);
}
private void makeRecently(int key){
Node x = map.get(key);
System.out.println("recently:"+x.key);
cache.removeList(x);
cache.addList(x); //重新插回队尾
}
private void addRecently(int key,int val){
Node x = new Node(key,val);
cache.addList(x);
map.put(key,x);
}
/* 删除最久未使用的元素 */
private void removeLeastRecently() {
// 链表头部的第一个元素就是最久未使用的
Node deletedNode = cache.removeListFirst();
// 同时别忘了从 map 中删除它的 key
int deletedKey = deletedNode.key;
System.out.println(deletedKey);
map.remove(deletedKey);
}
private void deleteKey(int key){
Node x = map.get(key);
cache.removeList(x);
map.remove(key);
}
}
class Node{
public Node next;
public Node pre;
public int key;
public int val;
public Node(int key,int val){
this.key = key;
this.val = val;
}
}
class DoubleList{
private Node head;
private Node tail;
private int size;
public DoubleList(){
head = new Node(0,0);
tail = new Node(0,0);
head.next = tail;
tail.pre =head;
size = 0;
}
public void addList(Node x){
//从尾部插入
x.pre = tail.pre;
tail.pre.next=x;
x.next = tail;
tail.pre = x;
size++;
}
public void removeList(Node x){
x.pre.next = x.next;
x.next.pre = x.pre;
size--;
}
public Node removeListFirst(){
if(head.next==tail){
return null;
}
//head.next = head.next.next;
//head.next.next.pre=head; 要返回删除的这个节点
Node first = head.next;
removeList(first);
return first;
}
public int size(){
return size;
}
}
/** * Your LRUCache object will be instantiated and called as such: * LRUCache obj = new LRUCache(capacity); * int param_1 = obj.get(key); * obj.put(key,value); */
利用Java内置LinkedHashMap实现
class LRUCache {
int cap;
LinkedHashMap<Integer, Integer> cache = new LinkedHashMap<>();
public LRUCache(int capacity) {
this.cap = capacity;
}
public int get(int key) {
if (!cache.containsKey(key)) {
return -1;
}
// 将 key 变为最近使用
makeRecently(key);
return cache.get(key);
}
public void put(int key, int val) {
if (cache.containsKey(key)) {
// 修改 key 的值
cache.put(key, val);
// 将 key 变为最近使用
makeRecently(key);
return;
}
if (cache.size() >= this.cap) {
// 链表头部就是最久未使用的 key
int oldestKey = cache.keySet().iterator().next();
cache.remove(oldestKey);
}
// 将新的 key 添加链表尾部
cache.put(key, val);
}
private void makeRecently(int key) {
int val = cache.get(key);
// 删除 key,重新插入到队尾
cache.remove(key);
cache.put(key, val);
}
}
LinkedHashMap
虽然增加了时间和空间上的开销,但是通过维护一个运行于所有条目的双向链表,LinkedHashMap保证了元素迭代的顺序。该迭代顺序可以是插入顺序或者是访问顺序。
| 关 注 点 | 结 论 |
|---|---|
| LinkedHashMap是否允许空 | Key和Value都允许空 |
| LinkedHashMap是否允许重复数据 | Key重复会覆盖、Value允许重复 |
| LinkedHashMap是否有序 | 有序 |
| LinkedHashMap是否线程安全 | 非线程安全 |
public class LinkedHashMap<K,V>
extends HashMap<K,V>
implements Map<K,V>
{
private transient Entry<K,V> header;
/** * The iteration ordering method for this linked hash map: true * for access-order, false for insertion-order. * true表示最近最少使用次序,false表示插入顺序 */
private final boolean accessOrder;
...
}
LinkedHashMap是HashMap的子类,自然LinkedHashMap也就继承了HashMap中所有非private的方法。
关于HashMap原理做了点笔记,也没有太理解,参考文章:
https://blog.csdn.net/qq_42194397/article/details/126059459?spm=1001.2014.3001.5501
边栏推荐
- 单壁碳纳米管-DNA复合物(SWCNT-DNA)|作用机理
- 七个易犯的 IT 管理错误—以及如何避免
- JSP Servlet JDBC MySQL CRUD Sample Tutorial
- Durable rules(持久规则引擎) 学习小记
- 回归——分层回归
- MSNs-SS-siRNA二氧化硅-二硫键-核酸RNA|HA-SS-siRNA,hyaluronic acid透明质酸修饰RNA(RNA修饰剂)
- Agile Organization | The path for enterprises to overcome the impact of the digital wave
- :style中颜色使用函数动态获取赋值
- [mathematical foundation] higher mathematics concept learning
- 博世集团启动量子数字孪生计划
猜你喜欢

EasyExce template filling generation of Excel of actual operation, many processing sheet page

RNA的化学修饰原理|Gal-PEG-siRNA|siRNA-S-S-DSPE|siRNA-s-s-PEG|cholesterol-siRNA

leetcode:952. 按公因数计算最大组件大小【并查集】

JMeter usage tutorial (2)

图床软件要收费,算了我自己写一个开源免费的。

There is a fee for the picture bed software. Forget it, I wrote an open source free one.

regular expression

Agile Organization | The path for enterprises to overcome the impact of the digital wave
![[GXYCTF2019]禁止套娃](/img/91/3f64bebd13a8b13fbb387c2acf8618.png)
[GXYCTF2019]禁止套娃

分布式限流 redission RRateLimiter 的使用及原理
随机推荐
这半年我做交易链路自动化回归的那些事儿...
关于安装软件时x86 ,x64,x86_64,ARM 64, ARM 32 的选择
论文写作全攻略|一篇学术科研论文该怎么写
Briefly talk about K-means clustering
The second growth curve | The driving guide for corporate innovation to break through the stagnation dilemma
通过观测云监控器监控基础资源,自动报警
7 行代码搞崩溃 B 站,原因令人唏嘘!
促进二十一世纪创客教育的新发展
OAuth,JWT ,OIDC你们搞得我好乱啊
用对象字面量或Map替代Switch/if语句
JMeter使用教程(二)
【无标题】
全排列的一点小技巧:康托展开
根据昵称首字母生成头像
C# WPF给综合实战项目加个帮助文档
ESP8266-Arduino programming example-LittleFS and data upload
如何优雅的自定义 ThreadPoolExecutor 线程池
双功能RGD-TAT修饰DNA纳米胶束|聚苯胺纳米线修饰DNA(PAINW/DNA)
一道菜撑起百亿估值的太二酸菜鱼,能否迈过食品安全这道坎?
优惠券系统设计思想