当前位置:网站首页>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
边栏推荐
- [mathematical foundation] probability and mathematical statistics related concept learning
- 一道菜撑起百亿估值的太二酸菜鱼,能否迈过食品安全这道坎?
- Samba服务器配置(什么情况下需要服务器)
- LeetCode 0144. 二叉树的前序遍历:二叉树必会题
- internship:利用easypoi将excel表数据导入导出
- 从专业角度分析国内创客教育发展
- Kotlin - 协程作用域 CoroutineScope、协程构建器 CoroutineBuilder、协程作用域函数 CoroutineScope Functiom
- Agile Organization | The path for enterprises to overcome the impact of the digital wave
- Single-core browser and what is the difference between dual-core browser, which to use?
- C# WPF给综合实战项目加个帮助文档
猜你喜欢
MSNs-SS-siRNA二氧化硅-二硫键-核酸RNA|HA-SS-siRNA,hyaluronic acid透明质酸修饰RNA(RNA修饰剂)
Hyaluronic acid-siRNA透明质酸修饰核糖核酸|peptide–siRNA 多肽偶连RNA/DNA核酸(齐岳PNA修饰物)
OAuth,JWT ,OIDC你们搞得我好乱啊
In the past six months, I have done those things about the automatic return of the transaction link...
mos管闩锁效应理解学习
聚丙烯微孔膜的等离子体改性及DNA|有机自由基改性DNA-阳离子脂质复合体的应用
Data visualization ---- web page displays temperature and humidity
Expert advice | How to formulate a growth strategy for survival in an economic downturn
ds1302——斌哥51
Detailed explanation of design ideas of webUI test framework
随机推荐
What are the software development modes (software engineering development mode)
PEG-PEI共聚物/DNA复合物|甘草次酸修饰的长循环阳离子脂质体DNA复合物|解析说明
太卷了,企业级的智慧物业系统,也完全开源....
关于论青少年尽早学少儿编程之说
通过观测云监控器监控基础资源,自动报警
json-c实现json和结构体之间的相互转换
The difference between uri and url is simple to understand (what is the difference between uri and url)
Sasser virus source code (ransomware source code)
conda virtual environment | install and list problems
探索创客教育在线管理实施体系
这半年我做交易链路自动化回归的那些事儿...
指定宽度截取字符串
图床软件要收费,算了我自己写一个开源免费的。
Summary of scratch learning related materials
Oracle问题: ORA-01882: 未找到时区
JSP Servlet JDBC MySQL CRUD 示例教程
荧光量子点修饰siRNA-QDs|纳米金修饰siRNA-Au(RNA修饰方式方法)
Briefly talk about K-means clustering
SwiftUI * @State 相关问题
五个供应商销售谈判策略的识别以及应对它们的方法