Q200510-03-03 :LRU缓存机制
LRU缓存机制
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。
获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果密钥已经存在,则变更其数据值;如果密钥不存在,则插入该组「密钥/数据值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。进阶:
你是否可以在 O(1) 时间复杂度内完成这两种操作?
示例:
LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // 返回 1
cache.put(3, 3); // 该操作会使得密钥 2 作废
cache.get(2); // 返回 -1 (未找到)
cache.put(4, 4); // 该操作会使得密钥 1 作废
cache.get(1); // 返回 -1 (未找到)
cache.get(3); // 返回 3
cache.get(4); // 返回 4
代码:
package test3; import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List; class Node {
int key;
int val;
Node next;
Node prev; public Node(int key, int val){
this.key = key;
this.val = val;
next = null;
prev = null;
}
} public class LruCache {
private int capacity;
private HashMap<Integer, Node> cacheMap;
private Node head, tail; public LruCache(int capacity) {
this.capacity = capacity;
this.cacheMap = new LinkedHashMap<>();
this.head = new Node(-1, -1);
this.tail = new Node(-1, -1);
head.next = tail;
head.prev = tail;
tail.next = head;
tail.prev = head;
} public int get(int key) {
if(!cacheMap.containsKey(key)) {
return -1;
}
Node node = cacheMap.get(key);
moveToHead(node);
return node.val;
} public void put(int key, int value) {
if (cacheMap.containsKey(key)) {
cacheMap.get(key).val = value;
moveToHead(cacheMap.get(key));
} else {
Node node = new Node(key, value);
if (cacheMap.size() >= this.capacity) {
Node rm = tail.prev;
deleteNode(rm);
cacheMap.remove(rm.key);
}
insertHead(node);
cacheMap.put(key, node);
}
} private void moveToHead(Node node) {
deleteNode(node);
insertHead(node);
} private void insertHead(Node node) {
Node next = head.next;
head.next = node;
node.prev = head;
node.next = next;
next.prev = node;
} private void deleteNode(Node node) {
Node front = node.prev;
Node end = node.next;
front.next = end;
end.prev = front;
} public void printCache() {
StringBuilder sb=new StringBuilder();
sb.append("["); List<String> ls=new ArrayList<String>();
for(int key:cacheMap.keySet()) {
Node value=cacheMap.get(key);
ls.add("("+key+","+value.val+")");
}
sb.append(String.join(",", ls)); sb.append("]");
System.out.println(sb.toString());
} public static void main(String[] args) throws Exception{
LruCache cache=new LruCache(2);
cache.put(1,1);
System.out.print(".....");
cache.printCache();
System.out.println(); cache.put(2,2);
System.out.print(".....");
cache.printCache();
System.out.println(); System.out.print(cache.get(1));
System.out.print(".....");
cache.printCache();
System.out.println(); cache.put(3, 3);
System.out.print(".....");
cache.printCache();
System.out.println(); System.out.print(cache.get(2));
System.out.print(".....");
cache.printCache();
System.out.println(); cache.put(4, 4);
System.out.print(".....");
cache.printCache();
System.out.println(); System.out.print(cache.get(1));
System.out.print(".....");
cache.printCache();
System.out.println(); System.out.print(cache.get(3));
System.out.print(".....");
cache.printCache();
System.out.println(); System.out.print(cache.get(4));
System.out.print(".....");
cache.printCache();
System.out.println();
}
}
输出:
.....[(1,1)] .....[(1,1),(2,2)] 1.....[(1,1),(2,2)] .....[(1,1),(3,3)] -1.....[(1,1),(3,3)] .....[(3,3),(4,4)] -1.....[(3,3),(4,4)] 3.....[(3,3),(4,4)] 4.....[(3,3),(4,4)]
--2020年5月11日--
Q200510-03-03 :LRU缓存机制的更多相关文章
- [Leetcode]146.LRU缓存机制
Leetcode难题,题目为: 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key ...
- Java实现 LeetCode 146 LRU缓存机制
146. LRU缓存机制 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - ...
- 常见面试题之操作系统中的LRU缓存机制实现
LRU缓存机制,全称Least Recently Used,字面意思就是最近最少使用,是一种缓存淘汰策略.换句话说,LRU机制就是认为最近使用的数据是有用的,很久没用过的数据是无用的,当内存满了就优先 ...
- Q200510-03-02: LRU缓存机制
问题: LRU缓存机制运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果 ...
- 力扣 - 146. LRU缓存机制
目录 题目 思路 代码 复杂度分析 题目 146. LRU缓存机制 思路 利用双链表和HashMap来解题 看到链表题目,我们可以使用头尾结点可以更好进行链表操作和边界判断等 还需要使用size变量来 ...
- 146. LRU 缓存机制 + 哈希表 + 自定义双向链表
146. LRU 缓存机制 LeetCode-146 题目描述 题解分析 java代码 package com.walegarrett.interview; /** * @Author WaleGar ...
- 【golang必备算法】 Letecode 146. LRU 缓存机制
力扣链接:146. LRU 缓存机制 思路:哈希表 + 双向链表 为什么必须要用双向链表? 因为我们需要删除操作.删除一个节点不光要得到该节点本身的指针,也需要操作其前驱节点的指针,而双向链表才能支持 ...
- 【力扣】146. LRU缓存机制
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果关键字 (key) ...
- [Swift]LeetCode146. LRU缓存机制 | LRU Cache
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
随机推荐
- SonarQube 自定义规则开发
SonarQube 自定义规则开发 满足一些特定需求的时候,需要自己开发代码规则. 环境 和前文的演示环境一致. 步骤 开发步骤见 Writing Custom Java Rules 101,这是官方 ...
- three.js 着色器材质之变量(三)
这篇郭先生在练习一下着色器变量,在度娘上面或者官网上经常看到类似水波一样的效果,这篇就试着做一个这样的效果,顺便巩固一下顶点着色器和片元着色器,毕竟多多练习才能更好地掌握.效果如下图,在线案例请点击博 ...
- 菊长说丨一文读懂MySQL4种事务隔离级别
经常提到数据库的事务,那你知道数据库还有事务隔离的说法吗,事务隔离还有隔离级别,那什么是事务隔离,隔离级别又是什么呢?今天我们就找菊长去,请他帮大家梳理一下这些各具特色的事务隔离级别,咱走着~~~ 点 ...
- Vue 如何优雅的根据条件动态显示组件
常规情况下,在里动态加载不同组件的方式为: <template> <!-- 符合条件A,加载组件A --> <BusinessComponentA v-if=" ...
- Linux学习日志——基本指令②
文章目录 Linux学习日志--基本指令② 前言 touch cp (copy) mv (move) rm vim 输出重定向(> 或 >>) cat df(disk free) f ...
- 谈谈 Qt4 中文乱码的解决
本文只描述Qt4的解决方法,Qt5没有尝试过,不做讨论.网上关于这个话题一搜一大堆,基本无外乎字符集编码的理论,看不明白.直接上代码吧! #include "widget.h" # ...
- MySQL · 性能优化 · MySQL常见SQL错误用法(转自-阿里云云栖社区)
作者:阿里云云栖社区链接:https://zhuanlan.zhihu.com/p/26043916来源:知乎著作权归作者所有,转载请联系作者获得授权. 前言 MySQL在2016年仍然保持强劲的数据 ...
- linux驱动之模块化编程小总结
本文包含了linux驱动模块化编程的基本,包括创建多线程,延时,以及makefile 以一个实例来说明 #include<linux/init.h> #include<linux/m ...
- python基础 Day10
python Day10 函数的参数升级版 形参角度 万能参数*arg #在函数定义时,*代表聚合.他将所有的位置参数聚合成一个元组,赋值给了args def test(*args): print(& ...
- 操作系统-PV习题
(1)阅览室问题:加入阅览室入口有一本登记册,每个人都必须按顺序签名进去. 想法:登记册可以用结构数组A[]表示,包含name和number.此外,还需要信号量seatcount表示剩余座位数. 使用 ...