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缓存机制的更多相关文章

  1. [Leetcode]146.LRU缓存机制

    Leetcode难题,题目为: 运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key ...

  2. Java实现 LeetCode 146 LRU缓存机制

    146. LRU缓存机制 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - ...

  3. 常见面试题之操作系统中的LRU缓存机制实现

    LRU缓存机制,全称Least Recently Used,字面意思就是最近最少使用,是一种缓存淘汰策略.换句话说,LRU机制就是认为最近使用的数据是有用的,很久没用过的数据是无用的,当内存满了就优先 ...

  4. Q200510-03-02: LRU缓存机制

    问题: LRU缓存机制运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果 ...

  5. 力扣 - 146. LRU缓存机制

    目录 题目 思路 代码 复杂度分析 题目 146. LRU缓存机制 思路 利用双链表和HashMap来解题 看到链表题目,我们可以使用头尾结点可以更好进行链表操作和边界判断等 还需要使用size变量来 ...

  6. 146. LRU 缓存机制 + 哈希表 + 自定义双向链表

    146. LRU 缓存机制 LeetCode-146 题目描述 题解分析 java代码 package com.walegarrett.interview; /** * @Author WaleGar ...

  7. 【golang必备算法】 Letecode 146. LRU 缓存机制

    力扣链接:146. LRU 缓存机制 思路:哈希表 + 双向链表 为什么必须要用双向链表? 因为我们需要删除操作.删除一个节点不光要得到该节点本身的指针,也需要操作其前驱节点的指针,而双向链表才能支持 ...

  8. 【力扣】146. LRU缓存机制

    运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果关键字 (key) ...

  9. [Swift]LeetCode146. LRU缓存机制 | LRU Cache

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

随机推荐

  1. 6、单例模式 Singleton模式 只有一个实例 创建型模式

    1.了解Singleton模式 程序在运行时,通常都会生成很多实例.例如,表示字符串的java . lang . string类的实例与字符串是- -对- -的关系,所以当有1000个字符串的时候,会 ...

  2. [vue]子组件通过props获取父组件数据以及使用watch解决动态数据不生效问题

    父子组件的传值,在Vue官方也写得很清楚,父组件中使用v-bind绑定传送,子组件使用props接收. 父组件通过v-bind绑定数据: <template> <router-vie ...

  3. 文章要保存为TXT文件,其中的图片要怎么办?Python帮你解决

    前言 用 python 爬取你喜欢的 CSDN 的原创文章,保存为TXT文件,不仅查看不方便,而且还无法保存文章中的代码和图片. 今天教你制作成 PDF 慢慢看.万一作者的突然把号给删了,也会保存备份 ...

  4. Vue 事件的$event参数=事件的值

    template <el-table :data="dataList"> <el-table-column label="id" prop=& ...

  5. Vue Vuex中的严格模式/实例解析/dispatch/commit /state/getters

    严格模式 import getters from './getters' import mutations from './mutations' import actions from './acti ...

  6. 如何为你的IDEA安装插件——几个实用插件推荐

    文章目录 如何为你的IDEA安装插件--几个实用插件推荐 安装插件 插件推荐 1.Background Image Plus 2.Translation 3.CodeGlance 4.Rainbow ...

  7. Android 开发学习进程0.12 自定义view activity的属性

    设置类似钉钉或tel的圆形用户名首字母头像 设置有两种方法,一是使用已有的库或自定义的view组件,但如果确定只是文字头像,也可使用textview的backgrou属性,调整资源文件使textvie ...

  8. Code Review 从失败中总结出来的几个经验

    资深的程序员都知道 Code Review 可以对代码质量,代码规范,团队代码能力提升带来很大的提升,还有著名的技术专家"左耳朵耗子"也说过: 我认为没有 Code Review ...

  9. 漏洞重温之XSS(上)

    漏洞简介 跨站脚本攻击(XSS)是指恶意攻击者往Web页面里插入恶意Script代码,当用户浏览页面之时,嵌入web网页中的script代码会被执行,从而达到恶意攻击用户的目的. XSS漏洞通常是通过 ...

  10. jraft日志复制

    jraft的日志复制是指从leader往follower复制logEntry的过程. 日志复制从节点成为leader开始.在nodeImpl的becomeLeader中 private void be ...