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 ...
随机推荐
- 将vscode打造成强大的C/C++ IDE
一.安装 你可以直接从微软官网下载,如果你想要一个纯净的vscode(微软官方的有一项商标.一个插件库.一个 C# 调试器以及遥测),可以手动编译https://github.com/microsof ...
- java方法与方法的重载
一 方法 1.方法的概述 在java中,方法就是用来完成解决某件事情或实现某个功能的办法. 方法实现的过程中,会包含很多条语句用于完成某些有意义的功能——通常是处理文本, 控制输入或计算数值.我们可以 ...
- C#LeetCode刷题-线段树
线段树篇 # 题名 刷题 通过率 难度 218 天际线问题 32.7% 困难 307 区域和检索 - 数组可修改 42.3% 中等 315 计算右侧小于当前元素的个数 31.9% 困难 4 ...
- C#设计模式之14-命令模式
命令模式(Command Pattern) 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/413 访问. 命令模式属于行 ...
- run as --> Maven clean 可以清除旧的jar包
run as --> Maven clean 可以清除旧的jar包
- 带你用 Python 实现自动化群控设备
1. 前言 群控,相信大部分人都不会陌生!印象里是一台电脑控制多台设备完成一系列的操作,更多的人喜欢把它和灰产绑定在一起! 事实上,群控在自动化测试中也被广泛使用!接下来的几篇文章,我将带大家聊聊企业 ...
- 【Codeforces】CF Round #592 (Div. 2) - 题解
Problem - A Tomorrow is a difficult day for Polycarp: he has to attend \(a\) lectures and \(b\) prac ...
- three.js 制作逻辑转体游戏(上)
今天郭先生又出来制作游戏了,最近有小伙伴要做一个逻辑转体小游戏,我怎么能不先来试试呢.玩法可以看上面的连接,下面附几张图.线案例请点击博客原文. 游戏规则不懂得可以看自行百度哈,其实玩起来还挺有难度的 ...
- docker入门2-docker service
docker service介绍 service是生产环境中某个image的container集合.一个service只使用一个image,但它编排这个image的运行方式,比如使用哪个端口,根据需求 ...
- 分享一个bootstrap的上一步,下一步的插件
效果图: 下载链接: https://www.daimabiji.com/index.php?m=content&c=down&a_k=ae0fI1gZyLT7oao56Pgu-dye ...